查看原文
人权观察

Rust 生态蜜蜂|Unsafe 随堂小测题解 Part6

张汉东 觉学社 2022-09-19
前言
因觉学,求绝学。Rust 生态蜜蜂,是觉学社公众号开启的一个付费专栏。生态蜜蜂,顾名思义,是从 Rust 生态的中,汲取养分,供我们成长。计划从2022年7月第二周开始,到2022年12月最后一周结束。预计至少二十篇周刊,外加一篇Rust年度报告总结抢读版。本专栏可以在公众号菜单「生态蜜蜂」中直接进入。海外用户可以去 https://rustbee.zhubai.love/ 订阅。

本篇是对第三篇随堂小测[1]中第12题和第13题的题解。

题目与题解

str_replace 函数为什么是不健全的?(10分)请增加测试用例,使该函数触发 UB。(10分)

/// !!!unsound!!!
pub fn str_replace(s: &str, from: &str, to: &str) -> String {
    if s.len() < from.len() {
        return s.to_owned();
    }

    let (s, from, to) = (s.as_bytes(), from.as_bytes(), to.as_bytes());
    let mut ans: Vec<u8> = Vec::new();

    unsafe {
        if from.is_empty() {
            for &b in s {
                ans.extend_from_slice(to);
                ans.push(b);
            }
            ans.extend_from_slice(to);
        } else {
            let mut i = 0;
            let end = s.len() - from.len();
            while i <= end {
                let probe = s.get_unchecked(i..i + from.len());
                if probe == from {
                    ans.extend_from_slice(to);
                    i += from.len();
                } else {
                    ans.push(s[i]);
                    i += 1;
                }
            }
        }

        String::from_utf8(ans).unwrap_unchecked()
    }
}

#[test]
fn test_str_replace() {
    assert_eq!(str_replace("abc""a""b"), "bbc");
    assert_eq!(str_replace("abc""""b"), "babbbcb");
    assert_eq!(str_replace("abc""a"""), "bc");
}

根据测试用例,知道这个str_replace函数的作用是把的from字符串替换为to字符串。

Safe Rust 中字符串维护的安全不变量(参考之前的文章)是让返回的 String 一定是合法的 UTF-8。上面示例中使用 Unsafe 代码处理字符串,做安全抽象就是要维护这个安全不变量。

具体来看上面代码处理字符串主要分两部分:from为空字符串或非空字符串。当from为空字符串时:

购买合集后可阅读剩余80%
#Rust生态蜜蜂
  • 1. Rust 生态蜜蜂|2022-7-24
  • 2. Rust 生态蜜蜂|2022-7-31
  • 3. Rust 生态蜜蜂|2022-08-01
购买合集后可阅读剩余80%

#Rust生态蜜蜂

微信扫一扫付费阅读本文

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存