zerx-lab-pencil-bin

maintainer sec-lab · 0 votes · scanned 2026-08-03 00:08:14.047287
LOW
View on AUR ↗
Why flagged The package downloads a prebuilt binary from the project's official domain (pen.dev), which is a legitimate source for the software; the download is not from a swappable or untrusted host, and the content is a standard proprietary application bundle.

Triggered rules

LOW AI review downgraded a static finding llm_review

The static rules flagged this MEDIUM, but an AI model (qwen/qwen3-235b-a22b-2507) reviewed the full PKGBUILD and judged it LOW (confidence 95%): The package downloads a prebuilt binary from the project's official domain (pen.dev), which is a legitimate source for the software; the download is not from a swappable or untrusted host, and the content is a standard proprietary application bundle.

1 higher static finding superseded - not the current verdict (shown for transparency)
MEDIUM source=() URL on a non-standard host 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:41 source_x86_64=("Pencil-${pkgver}-linux-x64.tar.gz::https://www.pen.dev/download/Pencil-linux-x64.tar.gz")

PKGBUILD

1 offending line(s) highlighted
1# Maintainer: zero <zero@localhost>
2# Automatically updated by GitHub Actions
3
4pkgname=zerx-lab-pencil-bin
5pkgver=1.2.0
6pkgrel=1
7pkgdesc="Pencil - Full canvas design tool with native performance"
8arch=('x86_64')
9url="https://www.pen.dev"
10license=('LicenseRef-proprietary')
11depends=(
12 'alsa-lib'
13 'at-spi2-core'
14 'cairo'
15 'dbus'
16 'expat'
17 'hicolor-icon-theme'
18 'libcups'
19 'libdrm'
20 'libsecret'
21 'libxcomposite'
22 'libxdamage'
23 'libxext'
24 'libxfixes'
25 'libxkbcommon'
26 'libxrandr'
27 'mesa'
28 'nspr'
29 'nss'
30 'pango'
31 'xdg-utils'
32)
33optdepends=(
34 'libappindicator: 系统托盘图标支持'
35 'libayatana-appindicator: 系统托盘图标支持(Ayatana)'
36)
37provides=('pencil')
38conflicts=('pencil')
39options=('!strip')
40
41source_x86_64=("Pencil-${pkgver}-linux-x64.tar.gz::https://www.pen.dev/download/Pencil-linux-x64.tar.gz")
42sha256sums_x86_64=('5cb28d5dcd3825c7f1c8e343706ccf6772f6244cce8e0ab6dea8a5c36933f700')
43
44# _extract_asar_file: 从 app.asar 中提取指定文件
45# 用法: _extract_asar_file <asar_path> <内部路径> <输出路径>
46#
47# 修复说明: asar 格式的 header 区域采用 Chromium pickle 封装,
48# 数据区起始位置 = 8 + header_size,需对齐到 4 字节边界。
49# 旧版代码直接用 f.tell() 获取 header_end,缺少对齐处理,
50# 导致偏移少 1 字节,提取出的文件前面带有垃圾数据。
51_extract_asar_file() {
52 python3 - "$1" "$2" "$3" << 'PYEOF'
53import struct, json, sys
54
55asar_path, inner_path, out_path = sys.argv[1], sys.argv[2], sys.argv[3]
56
57with open(asar_path, 'rb') as f:
58 # asar 格式 header 布局(均为 little-endian uint32):
59 # [0:4] pickle_size — 外层 pickle 的数据大小
60 # [4:8] header_size — 内层 header 区域的总大小(含 JSON 长度字段 + JSON 数据 + padding)
61 # [8:12] header_str_sz — header 字符串长度(= json_size + padding)
62 # [12:16] json_size — JSON 字符串的实际长度
63 f.read(4) # pickle_size(未使用)
64 header_size = struct.unpack('<I', f.read(4))[0]
65 f.read(4) # header_str_sz(未使用)
66 json_size = struct.unpack('<I', f.read(4))[0]
67
68 json_data = f.read(json_size)
69
70 # 数据区起始 = 8(前两个 uint32 字段自身)+ header_size
71 # 再向上对齐到 4 字节边界(pickle 对齐要求)
72 data_start = 8 + header_size
73 if data_start % 4 != 0:
74 data_start += 4 - (data_start % 4)
75
76 tree = json.loads(json_data)
77
78 def find_file(node, target, prefix=''):
79 if 'files' not in node:
80 return None
81 for name, child in node['files'].items():
82 path = f'{prefix}/{name}'.lstrip('/')
83 if path == target:
84 return child
85 result = find_file(child, target, path)
86 if result:
87 return result
88 return None
89
90 info = find_file(tree, inner_path)
91 if not info:
92 sys.exit(f'错误: 在 asar 中未找到 {inner_path}')
93
94 offset = int(info['offset'])
95 size = int(info['size'])
96 f.seek(data_start + offset)
97 data = f.read(size)
98
99 with open(out_path, 'wb') as out:
100 out.write(data)
101PYEOF
102}
103
104package() {
105 local _srcdir="Pencil-${pkgver}-linux-x64"
106 local _asar="$srcdir/$_srcdir/resources/app.asar"
107
108 # 安装主程序目录
109 install -d "$pkgdir/opt/pencil"
110 cp -r "$srcdir/$_srcdir/." "$pkgdir/opt/pencil/"
111
112 # chrome-sandbox 需要 setuid root
113 chmod 4755 "$pkgdir/opt/pencil/chrome-sandbox"
114
115 # /usr/bin 启动脚本
116 install -d "$pkgdir/usr/bin"
117 cat > "$pkgdir/usr/bin/pencil" << 'EOF'
118#!/bin/bash
119exec /opt/pencil/pencil "$@"
120EOF
121 chmod 755 "$pkgdir/usr/bin/pencil"
122
123 # 从 app.asar 提取图标(多尺寸)
124 # asar 内可用的图标:
125 # out/assets/512x512.png — 512x512 高分辨率图标
126 # out/editor/images/512x512.png — 同上(编辑器用)
127 # out/editor/images/64x64.png — 64x64 小图标
128 local _icon_512="$srcdir/pencil-512x512.png"
129 local _icon_64="$srcdir/pencil-64x64.png"
130
131 _extract_asar_file "$_asar" "out/assets/512x512.png" "$_icon_512"
132 _extract_asar_file "$_asar" "out/editor/images/64x64.png" "$_icon_64"
133
134 # 验证提取的图标是否为有效 PNG
135 for _icon_file in "$_icon_512" "$_icon_64"; do
136 if ! head -c8 "$_icon_file" | grep -q $'\x89PNG'; then
137 error "图标文件不是有效的 PNG: $_icon_file"
138 return 1
139 fi
140 done
141
142 # 安装多尺寸图标到 hicolor 主题
143 install -Dm644 "$_icon_512" "$pkgdir/usr/share/icons/hicolor/512x512/apps/pencil.png"
144 install -Dm644 "$_icon_64" "$pkgdir/usr/share/icons/hicolor/64x64/apps/pencil.png"
145
146 # 生成 128x128 中间尺寸(如果 ImageMagick 可用)
147 if command -v magick &>/dev/null; then
148 local _icon_128="$srcdir/pencil-128x128.png"
149 magick "$_icon_512" -resize 128x128 "$_icon_128"
150 install -Dm644 "$_icon_128" "$pkgdir/usr/share/icons/hicolor/128x128/apps/pencil.png"
151 elif command -v convert &>/dev/null; then
152 local _icon_128="$srcdir/pencil-128x128.png"
153 convert "$_icon_512" -resize 128x128 "$_icon_128"
154 install -Dm644 "$_icon_128" "$pkgdir/usr/share/icons/hicolor/128x128/apps/pencil.png"
155 fi
156
157 # 同时安装到 pixmaps 作为后备
158 install -Dm644 "$_icon_512" "$pkgdir/usr/share/pixmaps/pencil.png"
159
160 # .desktop 文件
161 # KDE Plasma Wayland 通过 desktopFileName 匹配 .desktop 文件名来查找图标。
162 # Electron 使用 package.json 的 productName("Pencil",大写 P)作为:
163 # - desktopFileName → KDE 用此匹配 .desktop 文件名(区分大小写)
164 # - resourceClass → 即 WM_CLASS / app_id
165 # 因此 .desktop 文件名必须为 Pencil.desktop,StartupWMClass 必须为 Pencil。
166 install -Dm644 /dev/stdin \
167 "$pkgdir/usr/share/applications/Pencil.desktop" << 'EOF'
168[Desktop Entry]
169Name=Pencil
170Comment=Full canvas design tool with native performance
171Exec=pencil %U
172Icon=pencil
173Terminal=false
174Type=Application
175Categories=Graphics;Design;
176MimeType=x-scheme-handler/pencil;
177StartupWMClass=Pencil
178StartupNotify=true
179EOF
180}
181

Changes since previous scan

--- PKGBUILD @ 2026-07-30 00:17
+++ PKGBUILD @ 2026-08-03 00:08
@@ -2,11 +2,11 @@
# Automatically updated by GitHub Actions
pkgname=zerx-lab-pencil-bin
-pkgver=1.1.70
+pkgver=1.2.0
pkgrel=1
pkgdesc="Pencil - Full canvas design tool with native performance"
arch=('x86_64')
-url="https://www.pencil.dev"
+url="https://www.pen.dev"
license=('LicenseRef-proprietary')
depends=(
'alsa-lib'
@@ -38,8 +38,8 @@
conflicts=('pencil')
options=('!strip')
-source_x86_64=("Pencil-${pkgver}-linux-x64.tar.gz::https://www.pencil.dev/download/Pencil-linux-x64.tar.gz")
-sha256sums_x86_64=('935a11317389077c7095d89009863f094e67f4b73f62c1dc6c0dbec4e29df408')
+source_x86_64=("Pencil-${pkgver}-linux-x64.tar.gz::https://www.pen.dev/download/Pencil-linux-x64.tar.gz")
+sha256sums_x86_64=('5cb28d5dcd3825c7f1c8e343706ccf6772f6244cce8e0ab6dea8a5c36933f700')
# _extract_asar_file: 从 app.asar 中提取指定文件
# 用法: _extract_asar_file <asar_path> <内部路径> <输出路径>

Scan history

Scanned at (UTC)SeverityRules
2026-08-03 00:08:14 LOW 2
2026-08-02 00:16:08 LOW 2
2026-08-01 00:11:18 LOW 2
2026-07-31 00:14:10 LOW 2
2026-07-30 03:13:55 MEDIUM 1
2026-07-30 00:17:23 LOW 2
2026-07-29 00:25:53 LOW 2
2026-07-28 00:07:28 LOW 2
2026-07-27 00:24:32 LOW 2
2026-07-26 00:07:32 LOW 2
2026-07-25 00:13:44 LOW 2
2026-07-24 00:02:28 LOW 2
2026-07-23 00:14:47 LOW 2
2026-07-22 00:29:32 LOW 2
2026-07-21 00:24:15 LOW 2
2026-07-20 00:19:49 LOW 2
2026-07-19 00:17:08 LOW 2
2026-07-18 00:14:48 LOW 2
2026-07-17 00:06:16 LOW 2
2026-07-16 00:05:41 LOW 2

Report a package

Reports go to the AURWatch maintainer (one person) and are read by hand. No login required.

0 / 4000
Your suggestion