| 136 | } |
| 137 | |
| 138 | static const char* |
| 139 | archive_fixpath(struct _reent *r, |
| 140 | const char *path, |
| 141 | archive_fsdevice **device) |
| 142 | { |
| 143 | ssize_t units; |
| 144 | uint32_t code; |
| 145 | const uint8_t *p = (const uint8_t*)path; |
| 146 | const char *device_path = path; |
| 147 | |
| 148 | // Move the path pointer to the start of the actual path |
| 149 | do |
| 150 | { |
| 151 | units = decode_utf8(&code, p); |
| 152 | if(units < 0) |
| 153 | { |
| 154 | r->_errno = EILSEQ; |
| 155 | return NULL; |
| 156 | } |
| 157 | |
| 158 | p += units; |
| 159 | } while(code != ':' && code != 0); |
| 160 | |
| 161 | // We found a colon; p points to the actual path |
| 162 | if(code == ':') |
| 163 | path = (const char*)p; |
| 164 | |
| 165 | // Make sure there are no more colons and that the |
| 166 | // remainder of the filename is valid UTF-8 |
| 167 | p = (const uint8_t*)path; |
| 168 | do |
| 169 | { |
| 170 | units = decode_utf8(&code, p); |
| 171 | if(units < 0) |
| 172 | { |
| 173 | r->_errno = EILSEQ; |
| 174 | return NULL; |
| 175 | } |
| 176 | |
| 177 | if(code == ':') |
| 178 | { |
| 179 | r->_errno = EINVAL; |
| 180 | return NULL; |
| 181 | } |
| 182 | |
| 183 | p += units; |
| 184 | } while(code != 0); |
| 185 | |
| 186 | archive_fsdevice *dev = NULL; |
| 187 | if(device != NULL && *device != NULL) |
| 188 | dev = *device; |
| 189 | else if(path != device_path) |
| 190 | dev = archiveFindDevice(device_path); |
| 191 | else if(archive_device_cwd != -1) |
| 192 | dev = &archive_devices[archive_device_cwd]; |
| 193 | if(dev == NULL) |
| 194 | { |
| 195 | r->_errno = ENODEV; |
no test coverage detected