Netty 同一个洞,90 天后换了编号又回来 —— 官方公告自己写着「上次修得不完整」

本篇话题 Netty CVE-2024-47535 CVE-2025-25193 2024-11-12

一句话 2024 年 11 月 12 日,Netty 发了新版本,宣布一个能把 Java 服务按死的洞修好了。 90 天后,同一个洞换了新编号又回来,官方公告自己写着「上次修得不完整」------ 因为空字节压根不计入长度,那道 8KB 的上限形同虚设。 又过了 34 天,官方挂在仓库里的那份公告,才把「该升到哪个版本」这一栏填上。

原始报告 github.com/advisories/GHSA-389x-839f-4rhx · github.com/netty/netty/issues/14795


各位老哥,今天这一篇,我得先把话说在前面:

这个洞打不到你的服务。

官方给它的向量是本地 ,要 Windows,要你自己机器上躺着一个 1GB 的文件, 还得赶在进程启动那一刻。没有任何远程攻击者能隔着网络把它递给你。

但它能卡住你的发版。

而且不是「可能」,是已经卡了好几个中文团队------ 下面会给你一条能自己验的依赖链。

还有一件事我想先说清楚 :这一篇里的技术结论, 我把这版和上版的源码拉下来,在真实 JVM 上编译跑过了。 不是读公告转述,是跑出来的。


先把这件事讲明白

不提术语。三句话。

第一句。

Netty 是 Java 那边写网络服务的框架。Dubbo、Seata、RocketMQ、Elasticsearch 后端, 底下都有它。你写的业务代码大概率一行 Netty 都不碰,但你的服务跑在它上面。

第二句。

2024 年 11 月 12 日,Netty 发了 4.1.115.Final, 宣布一个漏洞修好了:某个洞会让 Netty 在启动的时候, 把本地的某个文件整个读进内存。文件要是 1GB,你的 Java 进程就没了。

第三句。

90 天后,同一个洞换了新编号回来了。 新公告里有一句话,是官方自己写的: 「这个洞被修过,但那次修复不完整 ------ 空字节没有算进输入上限。」

第四次「修好了」是 34 天以后,而且改的不是代码,是公告上一个字段。


现场

项目 netty/netty 35,067 ★(2026-10-21 亲测)

这是几分的洞? CVE-2024-47535 给的是 CVSS v4 · 5.4 Moderate ; CVE-2025-25193 给的是 CVSS 3.1 · 5.5 Medium。 (两个号,分数对调了就写错了。)

攻击向量 Local(本地)

要什么条件? 一个 超过 1GB 的文件 + Windows + 进程启动的那一刻 。 (Linux 上 /etc/os-release 归 root 管,普通用户改不了。)

谁报的? CVE-2024-47535 的报告者是 Amossys-PGR ,另外三位分析师; CVE-2025-25193 的报告者是 chrisvest。

那今天还有洞吗?没有。 Netty 官网现在挂着的最新 4.1.x 是 4.1.139.Final(2026-10-06) 。 本文要讲的不是「现在还有洞」,是「当年那 34 天是怎么过去的」。

所以第一屏就得说清楚:这东西打不到你。

但真正会咬到中文工程师的,是另一头:

同一类东西被三套官方系统各记一份,其中一套当时还写着「没修」, 于是你的 CI 扫描器替你决定了发不发版。

这一篇讲的就是这个。


一、2024 年 11 月 12 日:第一次「修好了」

那天 Netty 发了 4.1.115.Final, release 页上的时间戳是 2024-11-12T11:19:02Z。

同一份 release 里挂着一笔修复 commit, 作者是 Norman Maurer (norman_maurer@apple.com)。

这笔 commit 的动机写得明明白白,逐字:

"We didnt verify the amount of data buffered while reading files / streams during startup which could allow an attacker to cause an OMME..."

(我们在启动期间读文件/读流的时候,没有核对读进去多少数据, 这可能让攻击者搞出一个 OOM......)

改法逐字:

"Decorate InputStream with own that will throw an exception once we reach the limit of data read."

(用一个自己写的 InputStream 包一层,读到的数据量一到上限就抛异常。)

同一天,Netty 自己在官网也发了公告,逐字:

"We are happy to announce the release of netty 4.1.115.Final. This is a bug-fix release but also include a fix for (CVE-2024-47535) which we rate as very low as the attacker needs to have access to the local filesystem with the right permissions."

(我们很高兴宣布 netty 4.1.115.Final 发布。 这是一个 bug 修复版本,同时也包含一个针对 CVE-2024-47535 的修复, 我们把它评为 very low,因为攻击者需要能访问本地文件系统,并且有相应的权限。)

「我们评为 very low」------这是官方自己的判断,一个字没改。

它新增了一个文件:common/src/main/java/io/netty/util/internal/BoundedInputStream.java,83 行。

这个类,就是那道判据本身。

它做的事情很简单:你在外面包一层,它就在里面数读了多少字节 , 数过 8KB 就抛 IOException。(这个 8KB 是类里的默认值,源码写的是 8 * 1024。)

顺带一提,同一天还发了一个 advisory: GHSA-xq3w-v528-46rv,也就是 CVE-2024-47535。 受影响 <= 4.1.114.Final,修复版本 4.1.115.Final。

到这儿为止,一切都对。


二、90 天后:同一个洞,换了个编号

2025 年 2 月 10 日 ,4.1.118.Final 发布(时间戳 2025-02-10T15:40:49Z)。

同一天,第二个 advisory 出来了: GHSA-389x-839f-4rhx,也就是 CVE-2025-25193。 受影响 < 4.1.118.Final,修复版本 4.1.118.Final。

距上一份公告,90 天。

顺带一提,4.1.118.Final 这一版在 Netty 官网的标题其实不是这个洞。 它开头写的是:

"This is a bug-fix release but also fixes a (critical CVE) in our SSL implementation."

(这是一个 bug 修复版本,同时也修复了 SSL 实现里的一个严重 CVE。)

这个洞排在这版的变更列表第二条 ,第一条是那个 SSL 的严重 CVE。 换句话说,4.1.118.Final 这版真正的 headline 是 SSL,不是这个。

这份新公告里有一句话,是本篇的支点。逐字:

"A similar issue was previously reported in GHSA-xq3w-v528-46rv This issue was fixed, but the fix was incomplete in that null-bytes were not counted against the input limit."

(有一个类似的问题之前报在 GHSA-xq3w-v528-46rv 下。 这个问题被修过,但那次修复不完整------空字节没有被算进输入上限。)

「上次修得不完整」,是官方自己写在公告里的。

这句话很硬。它意味着:第一次那份「已修复」,是假的。


三、公告说「修得不完整」,但没说完整在哪儿 ------ 我把源码拉下来编译了

公告只说了「空字节没算进上限」,没说这行代码在哪。

我不太信公告里的转述,于是把两个版本的源码原样拉下来, 在 OpenJDK 21 上编译跑了一遍。

先看这两个 tag 下源文件里的 read(),一个字节都没改过 (这是 release 里那份源文件本身,不是 diff):

java 复制代码
// 4.1.115.Final ------ 单字节 read()
public int read() throws IOException {
    checkMaxBytesRead(1);          // ← numRead 先 +1
    try {
        int b = super.read();
        if (b <= 0) {
            // We couldn't read anything.
            numRead--;             // ← 读到 0x00 时又减回来
        }
        return b;
    } ...
}

// 4.1.118.Final ------ 单字节 read()
public int read() throws IOException {
    checkMaxBytesRead();           // ← 不再预加
    int b = super.read();
    if (b != -1) { numRead++; }    // ← 只有 -1(EOF)不计数
    return b;
}

洞就在这两行的顺序里。

checkMaxBytesRead(1) 已经把 numRead 加了 1, 之后 b <= 0 又把它减掉 1。

所以:

  • 读到普通字节(b > 0)→ numRead 净增 1 → 计数正确;
  • 读到 0x00 (b == 0)→ numRead 净增 0 → 这个字节压根没被算进上限。

注意,不是「0x00 让计数倒退」。是「0x00 压根没被计数」。

numRead 永远追不上 maxBytesRead, 那道 8KB 的上限就形同虚设。

顺便说一句,官方自己是怎么描述这个洞的。

第二次那笔修复 commit 的说明里,逐字:

"The BoundedInputStream has a bug in counting the number of bytes read, where valid 0-bytes were not counted toward the limit."

(BoundedInputStream 在统计已读字节数上有个 bug, 有效的 0 字节没有被算进上限。)

"The BoundedInputStreamTest has also been made repeating, because it was already occasionally finding this problem. The test now passes consistently with the fixes."

(BoundedInputStreamTest 也被改成了重复执行 , 因为它本来就偶尔能抓到这个 bug。 现在这个测试在打了补丁之后能稳定通过。)

这一段是本篇我最想给你看的一句。

他们的测试早就偶尔能抓到这个 bug ------ 只是它「偶尔」出现,被当成了 flaky。 所以第二次的改法不是「找到并修好它」,而是「把测试改成重复执行」,让它稳定复现。

这是这个系列的老形状,又一次:判据在报警,但报警的人当成了噪音。

实测(-Xmx256m,3GB 全零稀疏文件,等价于 fsutil file createnew):

场景 / 4.1.115 / 4.1.118

  • 单字节 read() ------ 读完整个 1048576 字节,上限完全没拦住 ------ 第 8193 字节拦住
  • 批量 read(byte[]) ------ 第 8193 字节拦住 ------ 第 8193 字节拦住
  • readLine()(Netty 实际走的那条) ------ 第 8192 字节拦住 ------ 第 8193 字节拦住
  • 4.1.112 裸读 (= CVE-2024-47535 的根因) ------ ------ ------ OutOfMemoryError,撑爆 256MB 堆

4.1.112 那笔是真的复现成功了 :那个版本还没有 BoundedInputStream, 读 os-release 用的是裸的 new FileInputStream(file),没有任何上限 。 1GB 文件整个进堆,然后 OutOfMemoryError。

这四个格子,是我跑出来的,不是公告上抄的。

⚠️ 但有一条,我跑出来跟公告说的不一样

按 advisory 描述的 PoC(「4.1.115 也会被 1GB 文件撑爆」)------我复现不出来。

我加了个探针,看 readLine() 到底调哪个 read 重载:

lua 复制代码
readLine 期间: 单字节 read() 调用=0 次, 批量 read(byte[]) 调用=1 次

readLine() 走的是批量路径,单字节路径一次都没碰。 而 4.1.115 的批量路径计数是对的 → 8KB 就被拦住了。

所以准确的说法是:4.1.115 的洞只在单字节路径上,能不能打中取决于调用方怎么读。 本轮我没能定位到真实 Netty 里是哪个路径会走单字节。

这条我写进「本文不成立的结论」了。 公告说的 PoC 和实际调用路径对不上------这本身就是这个系列的老毛病。


四、修完 34 天,官方公告页还写着「没修」

2 月 10 日发完 4.1.118.Final,用户以为完事了。

2 月 11 日,有人来提 issue(#14795):

"The current version 4.1.118.Final does not fix this vulnerability in the description of..."

(当前的 4.1.118.Final 在描述里并没有修掉这个漏洞......)

1 分 36 秒后,维护者 Norman Maurer 回:

"Yes it was fixed... sorry the version range was incorrect. Just fixed this"

(是修了......抱歉,版本范围写错了。刚改了。)

但改的只是版本范围,公告页上「该升到哪个版本」那一栏还是错的。

于是接下来三天,issue 里陆陆续续冒出来:

  • 2 月 12 日 07:01 ------ 维护者又回了一句:「It is fixed in 4.1.118.Final」(在 4.1.118.Final 里已经修好了)
  • 2 月 12 日 12:35 ------ 「Trivy/Prisma 扫描还是过不去」
  • 2 月 13 日 ------ 「我下载的是 netty-common-4.1.118.Final,扫描器还在报 GHSA-389x-839f-4rhx」
  • 2 月 14 日 ------ 「+1,我这边也是,4.1.118.Final 一样报」

注意 2 月 12 日那两条的顺序:

上午 7 点,维护者说「已经修好了」。 下午 12 点半,扫描器说「还是过不去」。

中间隔了五个半小时。

2 月 14 日 ,安全团队的人 chrisvest 回了一句:

"The CVE has been updated... You need to contact your scanner tool vendors to get them to update."

(CVE 已经更新了......你得去联系你的扫描器厂商,让他们更新。)

这就是这三天的实况:

用户下载了官方说已经修好的 版本,扫描器照旧报警 , 官方给他的答案是「去催你的扫描器厂商」。

那它到底为什么报警?

3 月 16 日,有人把机制挖出来了(issue #14929):

"There are two GHSA-389x-839f-4rhx (CVE-2025-25193) pages: github.com/advisories/... github.com/netty/netty... The former has "Patched versions 4.1.118.Final", the latter has "Patched versions None". Please replace "None" with "4.1.118.Final" in the latter. Thanks!"

(有两个 GHSA-389x-839f-4rhx 的页面: 前一个写着「Patched versions 4.1.118.Final」,后一个写着「Patched versions None」。 请把后一个的 "None" 改成 "4.1.118.Final"。)

这就是全文最值钱的一段。

GitHub 上同一个编号,有两个「官方」页:

  • 全局 advisory database (github.com/advisories/...)

------ GitHub 统一收录的,有自己的字段;

  • 仓库级 advisory (github.com/<owner>/<repo>/security/advisories/...)

------ 由这个仓库自己的安全团队维护,有自己的字段。

两个字段,由两拨人、两条流程维护。 所以它们会漂移。

一个写着「已修复」,一个写着「没修」。 你的扫描器读哪一份,取决于它怎么实现。

「34 天」这个数是这么来的: 2025-02-10 修复发布 → 2025-03-16 有人提 issue = 34 天 。 chrisvest 在 10 小时 38 分后回了一句「Updated.」,然后关了 issue。


五、然后扫描器替你决定了发不发版

到这儿为止,这个洞在中文侧的真实痛感,还没人说破。

说破了它其实不是个远程 DoS。 本地向量、Windows、本地文件、启动那一刻。 你的服务不会被人隔空打挂。

但它是下面这个形状:

同一类东西被三套官方系统各记一份,其中一套当时还写着「没修」, 于是扫描器替你决定了发不发版。

而这套形状,在中文工程侧是真的会咬人的。

我拿 Maven 仓库的 POM 直接核了一条:

io.seata:seata-core 的最新版就是 2.0.0 (仓库里一共 31 个版本,2.0.0 是最后一个), 它的 POM 里钉着 netty-all 的版本是 4.1.86.Final。

lua 复制代码
io.seata:seata-core:2.0.0  →  io.netty:netty-all:4.1.86.Final

4.1.86 落在两条 CVE 的窗口里 (一条 <= 4.1.114.Final,一条 < 4.1.118.Final)。

Seata 就是那个分布式事务框架。

所以真实发生的事是这样的: Seata 的使用者想升 Netty 躲 CVE, 一看 Seata 自己的 POM 钉着 4.1.86; 不改 Seata 就得自己 override,改了 Seata 就得重新测一遍事务。

这就是「卡发版」。

而在 2 月那几天,这批人收到的官方答案是:「你去催你的扫描器厂商。」

判据在报警,报警的人被官方指去了另一个方向。


六、真正扎人的地方在哪

一件事里有三层「修好了」 ,而且三层全是官方自己说的:

层 / 谁说的 / 说了什么 / 实际是什么

  • 第一次 ------ Netty 官方,2024-11-12 ------ 「4.1.115.Final 修好了 CVE-2024-47535」 ------ 判据管不住:空字节不计数,8KB 上限形同虚设
  • 第二次 ------ Netty 官方,2025-02-10 ------ 「4.1.118.Final 修好了 CVE-2025-25193」 ------ 代码修了,但公告的版本范围写错 → 扫描器继续报警(2 月 12 日到 14 日)
  • 第三次 ------ chrisvest,2025-03-16 ------ 「Updated.」 ------ 把 None 改成 4.1.118.Final(10 小时 38 分后,距修复发布 34 天)

三层的形状还不一样: 第一次是判据本身有洞 (跑了 90 天才被发现); 第二次是修好了但信息送不到 ; 第三次是信息终于对了,但晚了 34 天。

这三条加起来,才是本系列的老形状:

判据在跑,但它管不住; 判据管住了,但结论送不到; 结论送到了,但晚了 34 天。

而且这一次,没有任何第三方用户被当成噪音关掉。 每一层都是官方自己发现、自己承认、自己改的。

这一点必须说清楚 ,否则就变成「厂商甩锅给用户」了------不是的。 官方每一步都认了,认得还挺快(1 分 36 秒、10 小时 38 分)。

问题不是他们不认。

问题是:一个东西要同时对三套官方系统、每一套都得记得手动同步, 它就迟早会漂。而漂了以后,代价落在谁的 CI 上,谁自己扛。


本篇不成立的结论

以下几条不能从本文推出去:

  1. 先说清楚:这不等于「Netty 不靠谱」。

CVE-2024-47535 是官方自己发现、自己修的(第一次修复在 2024-11-12,当天发版当天修); CVE-2025-25193 是官方自己承认「上次修得不完整」才发出来的。 本文盯的是「同一个洞 90 天后换号回来」这个形状,和它连带的 34 天漂移。

  1. 别写「这是个远程 DoS,攻击者能控制请求头」。

官方 CVSS 明写 AV:L(Local) ,Netty 官网自己的发布说明里写的是 "which we rate as very low as the attacker needs to have access to the local filesystem" 。 真要触发,得在目标 Windows 机器本地放一个 1GB 以上的文件 , 且在进程启动时 触发。没有任何请求头、包、协议层输入参与。 → 这句话写出来,懂行的人当场就戳穿了。

  1. 别写「4.1.115 也会被 1GB 文件撑爆」。

我复现不出来。 readLine() 走批量路径(探针实测:单字节 read() 调用 0 次), 而 4.1.115 的批量路径计数是对的,8KB 就被拦。 本文只说:这个类的洞客观存在,且已修复。

  1. 别写「某个具体的 Netty 路径会被打中」。

4.1.115 的洞只在单字节 路径上;本轮我没定位到真实 Netty 里哪条路径会走单字节。 复现的是机制,不是「Windows 上起 Netty 应用被 1GB 文件打死」这个完整场景。

  1. 别写「官方公告页现在还写着没修」。

它已经改了。 今天两个页面都是 4.1.118.Final 。 正确写法是「当时 仓库那份写着 None,全局那份写着 4.1.118.Final, 34 天后有人提 issue 才改成一致」。

  1. 别把「90 天」和「34 天」当成同一口径。

90 天 是两份 GHSA 公告日 之差(2024-11-12 → 2025-02-10),口径一致; 34 天 是修复版本发布日 → issue 提出日(2025-02-10 → 2025-03-16)。

  1. 别写「CVE-2025-25193 的受影响版本是 <= 4.1.118」。

GitHub Advisory 写的是 < 4.1.118.Final。 但 CVE 官方记录(cvelistV5)自己写的是 affected: "<= 4.1.118" 且状态为 affected ------ 而 4.1.118.Final 恰恰是修复版本。 → 这是第三套官方系统 的第三种说法。本文只陈述这个矛盾,不替它圆。

  1. 最后一条,关于「几个官方页面」。

本文写的是 两个 GHSA 页面 (全局 advisory database + 仓库级 advisory) 加一套 CVE 官方记录 。不是三个 GHSA。 而 CVE 官方记录那句 affected: "<= 4.1.118" 的矛盾, 我核到的是它写成了这样 ,我没有核到是谁维护的、为什么这么写。

📌 一条自己核出来的坑,记在这 :我第一版查 Netty 官网的发布说明时, 本机 curl 连了三次全是 HTTP:000,我据此在候选档里写了「netty.io 不可达」。 后来发现是本机代理 127.0.0.1:7890 抖动,加 --noproxy '*' 直连一次就通了。 → 上面引的那两句官网原文,是直连重取核到的逐字原文 , 页面是 netty.io/news/2024/11/12/4-1-115-Final.html(署名 normanmaurer,12-Nov-2024)。 → 教训 :抓不到先分清「路径 404」和「代理抖」。 这条和候选档里那条「HTTP:000 是代理抖动、要 --retry 2 --retry-delay 2」是同一个坑, 这次差点又踩一遍,还差点把一句真引语写成「查不到」。


复现

整套东西都在仓库里,不需要 Maven,不联网,JDK 17+ 就能跑:

bash 复制代码
cd experiments/netty-bounded-stream
./run.sh

它做四件事:

  1. 把 netty-4.1.115.Final 和 netty-4.1.118.Final 两个 tag 下的

BoundedInputStream.java 逐字放进两个独立包目录编译;

  1. 造一个 3GB 全零稀疏文件(等价于 fsutil file createnew 的效果,不占实际磁盘);
  2. 跑两个探针(readLine() 走哪个 read 重载 / 单字节路径上限是否失效);
  3. 复刻 PlatformDependent 的读法,验证 4.1.112 裸读会 OOM。

关键输出:

bash 复制代码
[单字节 read()] 读完 1048576 bytes → 上限【没拦住】!        ← 4.1.115
[单字节 read()] 被拦于第 8193 bytes                          ← 4.1.118
[PoC 路径 readLine()] 被上限拦住: Maximum number of bytes read: 8192   ← 4.1.115
→ OutOfMemoryError! 撑爆堆                                  ← 4.1.112 裸读

再验一下「两个官方页面」今天是不是一致:

perl 复制代码
# 全局 advisory database
curl -s https://github.com/advisories/GHSA-389x-839f-4rhx | grep -o "Patched versions[^<]*"

# 仓库级 advisory
curl -s https://github.com/netty/netty/security/advisories/GHSA-389x-839f-4rhx | grep -o "Patched versions[^<]*"

再验一下 Seata 那条依赖:

ruby 复制代码
curl -s https://maven.aliyun.com/repository/public/io/seata/seata-core/2.0.0/seata-core-2.0.0.pom \
  | grep -A3 netty-all

再验一下「34 天」:

perl 复制代码
# 4.1.118.Final 的发布时间
curl -s https://github.com/netty/netty/releases/tag/netty-4.1.118.Final | grep -o 'datetime="[^"]*"'

# issue #14929 的创建时间
curl -s https://api.github.com/repos/netty/netty/issues/14929 | grep -o '"created_at":"[^"]*"'

附:本文引用

都是公开地址,不用登录。

  • 第一次那份公告 → github.com/advisories/GHSA-xq3w-v528-46rv
  • 第二次那份公告 → github.com/advisories/GHSA-389x-839f-4rhx
  • 仓库级那份公告 → github.com/netty/netty/security/advisories/GHSA-389x-839f-4rhx
  • 第一次修复 commit → github.com/netty/netty/commit/fbf7a704a82e7449b48bd0bbb679f5661c6d61a3.patch
  • 第二次修复 commit → github.com/netty/netty/commit/d1fbda62d3a47835d3fb35db8bd42ecc205a5386.patch
  • 第一次发版 → github.com/netty/netty/releases/tag/netty-4.1.115.Final
  • 第二次发版 → github.com/netty/netty/releases/tag/netty-4.1.118.Final
  • Netty 官网 4.1.115 的发布说明(含「very low」那句)→ netty.io/news/2024/11/12/4-1-115-Final.html
  • Netty 官网 4.1.118 的发布说明(SSL 严重 CVE 排在前面)→ netty.io/news/2025/02/10/4-1-118-Final.html
  • 用户被卡的那三天 → github.com/netty/netty/issues/14795
  • 两个官方页面的矛盾 → github.com/netty/netty/issues/14929
  • CVE 官方记录(自带矛盾)→ raw.githubusercontent.com/CVEProject/cvelistV5/main/cves/2025/25xxx/CVE-2025-25193.json
  • OSV 记录 → api.osv.dev/v1/vulns/GHSA-389x-839f-4rhx
  • Seata 的 POM → maven.aliyun.com/repository/public/io/seata/seata-core/2.0.0/seata-core-2.0.0.pom
  • Seata 的全部版本 → maven.aliyun.com/repository/public/io/seata/seata-core/maven-metadata.xml
  • 本地复现 → experiments/netty-bounded-stream/

绝对时间一律取 GitHub release 页的 datetime 和 issue 的 created_at。 所有天数都是本机算的,不是估的。

所有引语逐字未改,译文一律放在中文括号里,不进逐字引语块。

📌 一条自己核出来的错,顺手记在这 : 我第一版把 4.1.115 的 CVSS 写成了 5.5。那是 CVE-2025-25193 的分。 CVE-2024-47535 给的是 CVSS v4 · 5.4 ,两个号对调着 。 规模数字和引语一个级别,不许拍脑袋填。

相关推荐
2501_946244785 小时前
开源鸿蒙平台 CMP 三方库「compose-continuous-rounded-corner-shape」适配全流程
华为·开源·harmonyos
wflynn5 小时前
GitHub 日榜趋势速报 | 2026-10-29
开源·github
2501_946244786 小时前
开源鸿蒙平台 CMP 三方库「Waterfall」适配全流程
华为·开源·harmonyos
2401_zq136y036 小时前
开源鸿蒙平台 CMP 三方库「Jewel」适配全流程
华为·开源·harmonyos
2601_949480067 小时前
开源鸿蒙平台 KMP 三方库「AutoLinkText」适配全流程
华为·开源·harmonyos
移动开发者实验室8 小时前
被 App Store 截图折腾了几次后,我开源了一个 AI 截图生成工具
人工智能·开源
miofly8 小时前
GitHub 今日推荐|Edge0:让大号 MoE 模型在一台 Mac 上流式跑起来
python·开源·github
2601_949480069 小时前
开源鸿蒙平台 CMP 三方库「reveal」适配全流程
华为·开源·harmonyos
2401_zq136y039 小时前
开源鸿蒙平台 CMP 三方库「KToast」适配全流程
华为·开源·harmonyos