随笔

Traversal-resistant file APIs

📌 一、路径遍历攻击是什么? 路径遍历(Path Traversal)攻击是一种安全漏洞,攻击者通过控制程序访问文件的路径,使程序打开了原本未授权访问的敏感文件。 📌 二、典型漏洞示例(易受攻击的代码) 存在漏洞的代码通常长这样: // baseDirectory 是受信任的固定目录 // filename 是用户可控制的输入 f, err := os.Open(filepath.Join(baseDirectory, filename)) 为什么这段代码有漏洞? 假设: baseDirectory := "/var/www/data" filename := "../../../../etc/passwd" 执行后: filepath.Join("/var/www/data", "../../../../etc/passwd") // 实际路径:"/etc/passwd" 攻击者成功跳出了本来限定的目录(/var/www/data),访问到了敏感文件。 📌 三、为什么传统路径检查不够安全? 你可能会想自己手动验证,比如: // 手动检查路径安全性(不推荐) if strings.Contains(filename, "..") { return errors.New("路径不安全") } f, err := os.Open(filepath.Join(baseDirectory, filename)) 但这种检查方式不安全,原因如下:

Mar 28, 2025

Goodbye core types-Hello Go as we know and love it!

📌 一、理解背景:Go语言泛型(Generics)的引入 在 Go 1.18(2022年3月发布)以前,Go语言并没有泛型功能(generics)。所谓泛型就是写函数或数据结构时,可以不指定具体类型,而用类型参数代替,然后调用时再填入具体类型,这样函数可以用于很多不同类型的情况。 比如: // 没有泛型之前,得为每种类型写一个函数 func SumInt(a, b int) int { return a + b } func SumFloat(a, b float64) float64 { return a + b } // 泛型后,可以只写一个函数: func Sum[T int | float64](a, b T) T { return a + b } 泛型的引入使Go语言更灵活、更强大。但随之而来,语言内部实现变得复杂了。 📌 二、理解类型参数、类型约束和类型集 泛型中出现了一些重要概念: 类型参数(Type Parameter) 就是泛型函数或泛型结构体中用来代替具体类型的占位符,类似函数参数。 func Example[T any](value T) T { return value } 这里T就是一个类型参数。 类型约束(Type Constraint) 表示一个类型参数能取哪些具体类型的限制。用接口表示: type MyConstraint interface { ~string | ~[]byte Hash() uint64 } 这个约束表示任何底层类型是string或[]byte,并且实现了Hash()方法的类型都可以满足。

Mar 28, 2025

From unique to cleanups and weak new low-level tools for efficiency

🧠 一、背景:为什么并发测试很难? Go 的并发编程很强大(goroutine + channel),但并发测试却非常难写、难维护。 1. 负面条件不好测试 比如你想测试某个函数 “还没有被调用” —— 你没法断言某事“没有发生”。 常见写法是等待一段时间: select { case <-calledCh: return true case <-time.After(10 * time.Millisecond): return false // 没被调用 } 这种测试方式: 速度慢:每个测试都等 10ms,几百个测试下来就很久了。 不稳定(flaky):在 CI 上容易失败,比如系统卡顿,10ms 不够就误判失败。 不优雅:测试中必须人为引入等待时间,还可能产生 race。 🌟 二、解决方案:synctest 包 Go 1.24 引入了 testing/synctest 实验包,让并发测试变得快速、稳定、无 race 条件。

Mar 28, 2025

From unique to cleanups and weak new low-level tools for efficiency

📌 背景与动机 在过去,Go 语言提供了 runtime.SetFinalizer 方法来处理对象被垃圾回收时的清理操作(Finalizer)。 但 Finalizer 存在一些固有问题: 如果对象之间有循环引用,Finalizer 可能永远不会被调用,导致内存泄漏。 Finalizer 会延迟对象的回收,至少需要两个垃圾回收周期才能彻底清除对象。 Finalizer 有可能让对象“复活”(Resurrection),导致原本应被释放的对象意外存活下来,造成内存浪费。 因此,Go 在 1.24 版本推出了两个新功能: runtime.AddCleanup:更安全的对象清理方法。 weak.Pointer:弱引用指针类型,可以引用对象但不会阻止对象被回收。 这两个功能结合使用,能有效解决传统 Finalizer 的问题,并构建更高效、更安全的数据结构,比如缓存或去重机制。 📌 一、runtime.AddCleanup(安全清理函数) runtime.AddCleanup 允许给一个对象附加一个“清理函数”,当该对象变得不可达(即垃圾回收后)时,清理函数将被执行。 示例:使用内存映射文件(memory-mapped file)

Mar 28, 2025

fuck the life!

随笔 最近有点迷茫,要学的东西很多,但是没有动力学习

Dec 28, 2024

fuck the life!

随笔 不知道写点什么,就随便写写

Dec 16, 2024