| 83 | |
| 84 | |
| 85 | Option<Error> validate(const string& role) |
| 86 | { |
| 87 | // We check * explicitly first as a performance improvement. |
| 88 | static const string* star = new string("*"); |
| 89 | if (role == *star) { |
| 90 | return None(); |
| 91 | } |
| 92 | |
| 93 | if (strings::startsWith(role, '/')) { |
| 94 | return Error("Role '" + role + "' cannot start with a slash"); |
| 95 | } |
| 96 | |
| 97 | if (strings::endsWith(role, '/')) { |
| 98 | return Error("Role '" + role + "' cannot end with a slash"); |
| 99 | } |
| 100 | |
| 101 | if (strings::contains(role, "//")) { |
| 102 | return Error("Role '" + role + "' cannot contain two adjacent slashes"); |
| 103 | } |
| 104 | |
| 105 | // Validate each component in the role path. |
| 106 | vector<string> components = strings::tokenize(role, "/"); |
| 107 | if (components.empty()) { |
| 108 | return Error("Role names cannot be the empty string"); |
| 109 | } |
| 110 | |
| 111 | static const string* dot = new string("."); |
| 112 | static const string* dotdot = new string(".."); |
| 113 | |
| 114 | foreach (const string& component, components) { |
| 115 | CHECK(!component.empty()); // `tokenize` does not return empty tokens. |
| 116 | |
| 117 | if (component == *dot) { |
| 118 | return Error("Role '" + role + "' cannot include '.' as a component"); |
| 119 | } |
| 120 | |
| 121 | if (component == *dotdot) { |
| 122 | return Error("Role '" + role + "' cannot include '..' as a component"); |
| 123 | } |
| 124 | |
| 125 | if (component == *star) { |
| 126 | return Error("Role '" + role + "' cannot include '*' as a component"); |
| 127 | } |
| 128 | |
| 129 | if (strings::startsWith(component, '-')) { |
| 130 | return Error("Role component '" + component + "' is invalid " |
| 131 | "because it starts with a dash"); |
| 132 | } |
| 133 | |
| 134 | if (component.find_first_of(*INVALID_CHARACTERS) != string::npos) { |
| 135 | return Error("Role component '" + component + "' is invalid " |
| 136 | "because it contains backspace or whitespace"); |
| 137 | } |
| 138 | } |
| 139 | |
| 140 | return None(); |
| 141 | } |
| 142 |
no test coverage detected