| 119 | } |
| 120 | |
| 121 | static size_t findAuthChallengeEnd(SC::StringSpan value, size_t start) |
| 122 | { |
| 123 | const SC::Span<const char> bytes = value.toCharSpan(); |
| 124 | const size_t length = bytes.sizeInBytes(); |
| 125 | bool quoted = false; |
| 126 | bool escaped = false; |
| 127 | |
| 128 | for (size_t idx = start; idx < length; ++idx) |
| 129 | { |
| 130 | if (quoted) |
| 131 | { |
| 132 | if (escaped) |
| 133 | { |
| 134 | escaped = false; |
| 135 | } |
| 136 | else if (bytes[idx] == '\\') |
| 137 | { |
| 138 | escaped = true; |
| 139 | } |
| 140 | else if (bytes[idx] == '"') |
| 141 | { |
| 142 | quoted = false; |
| 143 | } |
| 144 | continue; |
| 145 | } |
| 146 | |
| 147 | if (bytes[idx] == '"') |
| 148 | { |
| 149 | quoted = true; |
| 150 | continue; |
| 151 | } |
| 152 | |
| 153 | if (bytes[idx] != ',') |
| 154 | { |
| 155 | continue; |
| 156 | } |
| 157 | |
| 158 | const size_t tokenStart = skipAuthSpaces(bytes, idx + 1, length); |
| 159 | const size_t tokenEnd = readAuthToken(bytes, tokenStart, length); |
| 160 | if (tokenStart == tokenEnd) |
| 161 | { |
| 162 | return idx; |
| 163 | } |
| 164 | |
| 165 | const size_t afterToken = skipAuthSpaces(bytes, tokenEnd, length); |
| 166 | if (afterToken >= length or bytes[afterToken] != '=') |
| 167 | { |
| 168 | return idx; |
| 169 | } |
| 170 | } |
| 171 | |
| 172 | return length; |
| 173 | } |
| 174 | |
| 175 | static bool parseAuthRealm(SC::StringSpan value, size_t start, size_t end, SC::StringSpan& realm) |
| 176 | { |
no test coverage detected