1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use {
    crate::{
        parse::{PackageName, PackageVariant},
        RelativePackageUrl,
    },
    proptest::prelude::*,
};

/// Valid characters for a Fuchsia package path.  These characters are any unicode character,
/// except for '/', '\0', '.', and '\n'.
// TODO(https://fxbug.dev/42096516) allow newline once meta/contents supports it in blob paths
pub(crate) const ANY_UNICODE_EXCEPT_SLASH_NULL_DOT_OR_NEWLINE: &str = "[^/\0\\.\n]";

prop_compose! {
    pub(crate) fn random_package_segment()
        (s in r"[-0-9a-z\._]{1, 255}"
            .prop_filter(
                "Segments of '.' and '..' are not allowed",
                |s| s != "." && s != ".."
            )
        )
    -> String {
        s
    }
}

prop_compose! {
    pub fn random_package_name()(s in random_package_segment()) -> PackageName {
        s.parse().unwrap()
    }
}

prop_compose! {
    pub fn random_package_variant()(s in random_package_segment()) -> PackageVariant {
        s.parse().unwrap()
    }
}

prop_compose! {
    fn always_valid_resource_path_char()(c in ANY_UNICODE_EXCEPT_SLASH_NULL_DOT_OR_NEWLINE) -> String {
        c
    }
}

prop_compose! {
    pub fn random_relative_package_url()(s in random_package_segment()) -> RelativePackageUrl {
        s.parse().unwrap()
    }
}

prop_compose! {
    pub(crate) fn always_valid_resource_path_chars
        (min: usize, max: usize)
        (s in prop::collection::vec(always_valid_resource_path_char(), min..max)) -> String {
            s.join("")
        }
}

prop_compose! {
    pub fn random_resource_path
        (min: usize, max: usize)
        (s in prop::collection::vec(always_valid_resource_path_chars(1, 4), min..max))
         -> String
    {
        s.join("/")
    }
}

#[cfg(test)]
prop_compose! {
    pub(crate) fn random_resource_path_with_regex_segment_string
        (max_segments: usize, inner: String)
        (vec in prop::collection::vec(
            always_valid_resource_path_chars(1, 3), 3..max_segments),
         inner in prop::string::string_regex(inner.as_str()).unwrap())
        (index in ..vec.len(),
         inner in Just(inner),
         vec in Just(vec))-> String
    {
        let mut vec = vec;
        vec[index] = inner;
        vec.join("/")
    }
}

#[cfg(test)]
prop_compose! {
    pub(crate) fn random_resource_path_with_regex_segment_str
        (max_segments: usize, inner: &'static str)
        (s in random_resource_path_with_regex_segment_string(
            max_segments, inner.to_string())) -> String
    {
        s
    }
}