首页 文章 精选 留言 我的

精选列表

搜索[patch],共1794篇文章
优秀的个人博客,低调大师

Android Studio 2020.3.1 (Arctic Fox) Patch 3 发布

Android Studio2020.3.1(代号"Arctic Fox")稳定版已发布。 从 2020.3.1 起,Android Studio 开始启用新的版本号命名方案。2020.3.1 即为原计划的 4.3。谷歌称采用新的方案主要是为了与 IntelliJ 的版本对齐。 此版本的更新内容主要是 Bugfix: Android Gradle Plugin Issue #198453608:lint 独立插件无法正确处理 gradleApi() 依赖项 Issue #183632446: 当 Gradle build 在 Studio 之外运行时会触发 JPS build Issue #198667126: 在包含生成源的处理器的项目中同时启用 KSP 和 Kapt 会破坏 BundleLibraryClassesInputs C++ Editor Issue #197323118:UI 因后台长时间的 JniReferencesSearch 计算而被冻结 Database Inspector Issue #161081452: 支持保存 DBs Issue #195968515: 当路径中有空格时,无法使用App Inspection/Database Inspector导出数据 Dexer (D8) Issue #197625454: Java lambda 在对 class 进行 subclass 操作时导致意外行为 Shrinker (R8) Issue #197754200: 'Cannot constrain type' error during r8 minification Issue #200057495: 运行 R8 3.0.69 (from AGP 7.0.2) 和 3.0.72 时出现问题 详情查看 release notes。 下载地址:https://developer.android.com/studio/#downloads

优秀的个人博客,低调大师

时间账本 × 时间机器:六次 patch,一条信任链

2026-09-27 · 文章 GPL-3.0 / 工具 Apache-2.0 · GitHub 仓库 `Lennonhaha/fibemate-tools` > 工具文章容易写成决定清单:我们决定用 pkijs,我们决定加 --follow。决定是结果。结果谁都能抄,过程抄不走。这篇只写过程——六次失败,每次都写「试了什么、为什么错、怎么发现」。密码工程里,失败的原因比成功的方法活得久。——题记 ## 一、负例腐烂(时间账本) 时间账本要证明自己会失败。`scripts/smoke-freetsa-verify.mjs` 里有一条负例断言:拿一个错误的证书 pin 集去验 TSR,必须验签失败、必须 fail-closed。「错误的 pin 集」用的是 `pinned-certs.pem`。 2026-09-23 给账本加外部 FreeTSA 锚定块(PR #30),顺手动了夹具:为第 3 个块把 FreeTSA 的证书也放进了 `pinned-certs.pem`。没人改负例。 负例从此变成这样:拿 FreeTSA 的 pin 集去验 FreeTSA 签发的 TSR——验签当然通过。断言期待的失败没来,测试全绿。失败路径被静默移除,CI 上一点动静都没有。 修正(PR #31)花了三层: 1. 按解析后的 X509 subject 过滤 `pinned-certs.pem`,只留项目自己的 Test TSA 证书。pin 集这才真正「错」。 1. 不能用文本子串匹配 PEM——PEM 正文是 base64,换行一变匹配就失效。改用 `node:crypto` 的 `X509Certificate.subject`。 1. 同步删掉 `www/README.md` 里已不成立的「not yet committed」说明。 可迁移的结论只有一句:负例的失败路径会随夹具演化静默消失。夹具不是测试,夹具是会腐烂的测试。 ## 二、门禁拆了,债从缺口进来(时间账本) CI 卡住的时候,PR #15 做了一个交换:把 ledger-ci.yml 里的 Typecheck 步骤删掉,先让流水线绿。 同一天,TypeScript 就把账送来了。`makeBlock()` 返回 `Record`,所以 `genesis.hash_now` 的类型是 `unknown`。把它传给 `makeBlock` 的 `hash_prev: string` 参数,TS2322。同一个文件里 L181 对同一模式已经写了 `as string`,L235 漏了——一个字的债。 修复(PR #16)是给 L235 补 `as string`,然后把 Typecheck 步骤装回 CI。两个 PR 的合并时间相隔 11 分钟(01:16Z → 01:27Z)。删门禁的代价不是「几小时后」,是立即。 这次失败的价值不在那一行。在于它证明了:删门禁换来的 CI 绿是借来的。编译器抓住的错误,测试抓不住——`npm test` 一直是绿的,TS2322 不影响运行时行为,它只在类型层面存在。类型层面的债没有运行时症状,唯一的报警器就是那个被拆掉的步骤。 ## 三、一个工具里两套「验」的定义(时间账本) 更隐蔽的一处:同一个账本工具里,`VerifyTSR` 存在过两个不兼容的定义。 `core.ts` 的是三参数同步签名 `(tsrRef, ts, tsrDigest) => boolean`;`tsr.ts` 的是单参数异步 `(digest) => Promise`。CLI 层用一个临时桥接函数把两边缝起来,TODO 里挂着「长期统一」的标记,编号 CLI-DESIGN-1。 桥接期的问题是结构性的:每个调用点都要自己记住「现在在跟哪套合同说话」。缝的时候没错,但缝的数量会涨。 PR #22 把合同统一为 `(digest: string) => Promise`,`verifyChain` 改为 async,`cli.ts` 直接调 `makeVerifyTSR`,genTime 交叉核对单独走。改动只有十几行,前置的讨论比改动长。 结论:两套合同并存时,桥接函数不是解决方案,是缓刑。统一要趁调用点还少的时候做。 ## 四、git 语义交手三次(时间机器) 时间机器的输入是 git。git 的语义三次和预期不一致。 **第一次:单 commit 仓里 `-S` 返回空。** CI 环境没有真实仓库,最初没法跑测试。改成自建临时仓(提交 `bafa255`):建一个 git 仓,commit 1 引入 `foo`,commit 2 引入 `bar`。第一版临时仓只建了单个 commit——`git log -S bar` 返回空,因为符号没有「被引入」这个事件,它一直在。这是 git 的语义:pickaxe 追踪的是出现次数的变化。测试仓必须至少两个 commit。 **第二次:重命名断史。** `git log ` 只走文件名。文件改过名,历史就断成两截,改名前的一切消失。PR d3bee69(2026-09-24)给 `collect_file_history` 加 `--follow`,并把解析拆成独立的 `parse_git_log`。文档字符串里写清了边界:`--follow` 追踪重命名,但它是路径历史,不是符号追踪——要回答「这行代码哪来的」,仍然要用 `-S`。 **第三次:环境变量名传错,静默跑错仓库。** 时间机器有两个环境变量命名空间:`ctime/core.py:23` 读 `CTM_REPO`,`test/local_test.py:20` 读 `CTM_TEST_REPO`,默认值都是当前目录。跑测试的时候传了 `REPO=...`——三个名字一个都不匹配,Python 不报错,默认值接管,测试对着 `fibemate-tools` 自己的目录跑,FAIL,而且是解释不了为什么 FAIL 的 FAIL。 根子在文档:当时仓库根 README 写的是 `REPO=/path/to/repo python test/local_test.py`,代码读的是 `CTM_TEST_REPO`——文档给的名字就是错的。更早一版 README 的默认值写的是开发机绝对路径。修正把那一行改成 `CTM_TEST_REPO=/path/to/repo ...`(`README.md:53`)。这次修正没有独立 PR,随恢复提交 `dc25c20` 一起进来。 三个都是 git 或 shell 的默认行为在替你做决定。失败的时候先查默认值接管了什么。 ## 五、两条线怎么咬合 两个工具各答一半问题。 时间账本回答「以谁为准」:一个声明在某时刻存在,由谁的密钥签名、锚在哪个账本上、验签走哪条信任链。时间机器回答「什么时候变的」:一个符号、一个文件,在 git 历史里的引入和消失点。 咬合处的合同是 PR #22 定的:两处对 TSR 验证的判定统一成一个签名。盘点(CBOM 工具)给出资产清单,账本给清单盖章,时间机器追溯清单里每一项的来历。三条线各自的发布文章都写过;合起来看,这条线是完整的时间语义:**是什么(盘点)、何时为真(存证)、如何演变(考古)**。 ## 六、边界 三条,照旧不软: 1. **负例防腐没有系统性方案。** 负例腐烂不报警:引入(PR #30,09-23 11:09Z 合并)和修正(PR #31,同日 14:29Z 合并)相隔 3 小时 20 分,中间没有报警器响过。这次发现不构成方法论。能做的下一步是把「负例必须断言特定错误码」从约定变成测试。 1. **smoke 脚本不是 CI 步骤。** `smoke-freetsa-verify.mjs` 定位是手动检查,不在流水线里——它依赖真实网络锚定服务,CI 里不可复现。 1. **`--follow` 的边界是 git 的边界。** 它追踪重命名的能力依赖 diff 相似度启发,重写历史、大改内容后再改名,照样断。 ## 词汇注释 - **TSR**:Time Stamp Response,RFC 3161 时间戳响应,含签名与 genTime。 - **信任锚 pinning**:只信任预先固定的证书集,而非系统信任库。 - **fail-closed**:验证失败时拒绝,而不是放行。 - **git pickaxe(-S)**:追踪某符号在历史中出现次数变化的检索方式。 - **负例测试**:断言「错误输入必须失败」的测试。 ## 参考实践 - 账本:`Lennonhaha/fibemate-tools` → `crypto-time-ledger/` - 时间机器:`Lennonhaha/fibemate-tools` → `crypto-time-machine/` - 提交与 PR 号:均在上述仓库的 git 历史中,`git log ` 与 `gh pr view ` 可查 - 负例修正:`fibemate-tools` PR #31(`c4f668f`);合同统一:PR #22(`68d59d9`);`--follow`:PR #33(`d3bee69`);外部锚定:PR #30;TS2322 与 typecheck 恢复:PR #16(`724949d`);CI 临时仓:提交 `bafa255`(无 PR);README 变量名修正:随 `dc25c20`(无独立 PR)

优秀的个人博客,低调大师

时间账本 x 时间机器:六次 patch,一条信任链

>文章工具链已完成决定清单:我们决定用 pki,我们决定去走。决定是结链,结果能打脸,过程才能写。这篇只写过程——六次失败,每次都写了「为什么错、怎么发现」。密码工程里,失败的原因比成功的方法活得更久。——题记 ## 一、负例腐烂(时间账本) 时间账本证明自己会失败。`scripts/smoke-freetsa-verify.mjs` 里有一条负例断言:拿一个错误的证书 pin 集去验 TSR,必须验签失败、必须 fail-closed。**「错误的 pin 集」用的是 `pinned-certs.pem`。** 2026-09-23 给账本加外部 FreeTSA 锚定块(PR #30),顺手动了夹具:为第 3 个块把 FreeTSA 的证书也放进了 `pinned-certs.pem`。没人改负例。 负例从此变成这样:拿 FreeTSA 的 pin 集去验 FreeTSA 签发的 TSR——验签当然通过。断言期待的失败没来,测试全绿。失败路径被静默移除,CI 上一点动静都没有。 修正(PR #31)花了两层: 1. 解析后的 X509 subject 过滤 `pinned-certs.pem`,只留项目自己的 Test TSA 证书。pin 集这才真正「错」。 2. 不能用文本子串匹配 PEM——PEM 正文是 base64,换行一变匹配就失效。改用 `node:crypto` 的 `X509Certificate.subject`。 3. 同步删掉 `www/README.md` 里已不成立的「not yet committed」说明。 可迁移的结论只有一句:**负例的失败路径会随夹具演化静默消失。夹具不是测试,夹具会腐烂的测试。** ## 二、门禁拆了,债从缺口进来(时间账本) CI 卡住的时候,PR #15 做了一个交换:把 `ledger-ci.yml` 里的 Typecheck 步骤删掉,先让流水线绿。 同一天,TypeScript 就把债送来了。`makeBlock()` 返回 `Record`,所以 `genesis.hash_now` 的类型是 `unknown`。把它传给 `makeBlock` 的 `hash_prev: string` 参数,TS2322。同一个文件里 L181 对同一模式已经写了 `as string`,L235 漏了一个字的债。 修复(PR #16)是给 L235 补 `as string`,然后把 Typecheck 步骤装回 CI。两个 PR 的合并时间相隔 11 分钟(01:16Z -> 01:27Z)。**删门禁的代价不是「几小时后」,是立即可。** 这次失败的价值不在那行,在于它证明了:删门禁换来的 CI 绿是借来的。编译器抓住的错误,测试抓不住——`npm test` 一直是绿的,TS2322 不影响运行时行为,它只在类型层面存在。类型层面的债没有运行时症状,唯一的报警器就是那个被拆掉的步骤。 ## 三、一个工具里两套「验」的定义(时间账本) 更隐蔽的一处:同一个账本工具里,`VerifiyTSR` 存在两个不兼容的定义。 `core.ts` 的是三参数同步签名 `(tsrRef, ts, tsrDigest) => boolean`;`ts.ts` 的是单参数异步 `(digest) => Promise`。CLI 层用一个临时桥接函数把两边缝起来,TODO 里挂着「长期统一」的标记,编号 CLI-DESIGN-1。 桥接的问题是结构性的:每个调用点都要自己记住「现在跟哪套合同说话」。缝的时候没错,但缝的数量会涨。 PR #22 把命令统一为 `(digest: string) => Promise`,`verifyChain` 改为 `async`,`cli.ts` 直接调 `makeVerifyTSR`,`genTime` 交叉核对单独走。改动只有十几行,前置的讨论比改动长。 结论:两套合同并存时,桥接函数不是解决方案,是缓刑。**统一要趁调用点还少的时候做。** ## 四、git 语义交手三次(时间机器) 时间机器的输入是 `git`。`git` 的语义三次和预期不一致。 **第一次:单 commit 仓里 `-S` 返回空。** CI 环境没有真实仓库,最初没法跑测试。改成自建临时仓(提交 `bafa255`):建一个 git 仓,commit 1 引入 `foo`,commit 2 引入 `bar`。第一版临时仓只建了单个 commit——`git log -S bar` 返回空,因为符号没有「被引入」这个事件,它一直在。这是 `git` 的语义:pickaxe 追踪的是出现次数的变化。测试仓必须至少两个 commit。 **第二次:重命名断史。** `git log ` 只写文件名,文件改过名,历史就断成两截,改名前的一切消失。PR d3bee69 (2026-09-24) 给 `collect_file_history` 加 `--follow`,并把解析拆成独立的 `parse_git_log`。文档字符串里写清了边界:`--follow` 追踪重命名,但它是路径历史,不是符号追溯——要回答「这行代码哪来的」,仍然要用 `-S`。 **第三次:环境变量名传影,静默跑错仓库。** 时间机器有两个环境变量命名空间:`ctime/core.py:23` 读 `CTM_REPO`,`test/local_test.py:20` 读 `CTM_TEST_REPO`,默认值都是当前目录。跑测试的时候传了 `REPO=...` ——三个名字一个都不匹配,`pytest` 不报错,默认值接管,测试对着 `fibemate-tools` 自己的目录跑,FAIL,而且是解释不了为什么 FAIL 的 FAIL。 根子在文档:当时仓库根 README 写的是 `REPO=/path/to/repo python test/local_test.py`,代码读的是 `CTM_TEST_REPO`——文档给的名字就是错的。更早一版 README 的默认值写的是开发机绝对路径。修正把那行改成 `CTM_TEST_REPO=/path/to/repo ...` (`README.md:53`)。这次修正没有独立 PR,随修复提交 `dc25c20` 一起进来。 三个都是 `git` 或 `shell` 的默认行为在替你做决定。失败的时候先查默认值接管了什么。 ## 五、两条线怎么咬合 两个工具各答一半问题。 时间账本回答「以谁为准」:一个声明在某时刻存在,由谁的密钥签名、锚在哪个账本上、验签走哪条信任链。 时间机器回答「什么时候变的」:一个符号、一个文件,在 `git` 历史里的引入和消失点。 咬合处的合同是 PR #22 定的:两处对 TSR 验证的判定统一成一个签名。盘点(CBOM 工具)给出资产清单,账本给清单盖章,时间机器追溯清单里每一项的来历。三条线各自的发布文章都写过;合起来看,这条线是完整的时间语义:**是什么(盘点)、何时为真(存证)、如何演变(考古)。** ## 六、边界 三条,照旧不软: 1. **负例防腐没有系统性方案。** 负例腐烂不报警:引入(PR #30,09-23 11:09Z 合并)和修正(PR #31,同日 14:29Z 合并)相隔 3 小时 20 分,中间没有报警器响过。这次发现不构成方法论。能做的下一步是把「负例必须断言特定错误码」从约定变成测试。 2. **smoke 脚本不是 CI 步骤。** `smoke-freetsa-verify.mjs` 定位是手动检查,不在流水线里——它依赖真实网络锚定服务,CI 里不可复现。 3. **`--follow` 的边界是 `git` 的边界。** 它追踪重命名的能力依赖 diff 相似度启发,重写历史、大改内容后改名,照样断。 ## 词汇注释 - **TSR**:Time Stamp Response,RFC 3161 时间戳响应,含签名与 genTime。 - **信任锚 pinning**:只信任预先固定的证书集,而非系统信任库。 - **fail-closed**:验证失败时拒绝,而不是放行。 - **git pickaxe (-S)**:追踪某符号在历史中出现次数变化的检索方式。 ---- **参考:** - 时间机器:`Lennonhaha/fibemate-tools` → `crypto-time-machine/` - 提交与 PR 号:均在上述仓库的 git 历史中,`git log ` 与 `gh pr view ` 可查 - 负例修正:`fibemate-tools` PR #31(`c4f668f`);合同统一:PR #22(`68d59d9`);`--follow`:PR #33(`d3bee69`);外部锚定:PR #30;TS2322 与 typecheck 恢复:PR #16(`724949d`);CI 临时仓:提交 `bafa255`(无 PR);README 变量名修正:随 `dc25c20`(无独立 PR) 声明:本文由作者授权腾讯云开发者社区发布,未经许可,不得转载。 如有版权问题,请联系 `cloudcommunity@tencent.com` 删除。

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册