1044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath/*
2044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath * Copyright (C) 2014 The Android Open Source Project
3044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath *
4044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath * Licensed under the Apache License, Version 2.0 (the "License");
5044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath * you may not use this file except in compliance with the License.
6044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath * You may obtain a copy of the License at
7044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath *
8044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath *      http://www.apache.org/licenses/LICENSE-2.0
9044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath *
10044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath * Unless required by applicable law or agreed to in writing, software
11044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath * distributed under the License is distributed on an "AS IS" BASIS,
12044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath * See the License for the specific language governing permissions and
14044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath * limitations under the License.
15044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath */
16044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath
17044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath#ifndef LIBZIPARCHIVE_ENTRY_NAME_UTILS_INL_H_
18044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath#define LIBZIPARCHIVE_ENTRY_NAME_UTILS_INL_H_
19044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath
20044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath#include <stddef.h>
21044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath#include <stdint.h>
22044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath
23044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath// Check if |length| bytes at |entry_name| constitute a valid entry name.
24044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath// Entry names must be valid UTF-8 and must not contain '0'.
25044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamathinline bool IsValidEntryName(const uint8_t* entry_name, const size_t length) {
26044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath  for (size_t i = 0; i < length; ++i) {
27044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath    const uint8_t byte = entry_name[i];
28044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath    if (byte == 0) {
29044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath      return false;
30044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath    } else if ((byte & 0x80) == 0) {
31044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath      // Single byte sequence.
32044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath      continue;
33044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath    } else if ((byte & 0xc0) == 0x80 || (byte & 0xfe) == 0xfe) {
34044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath      // Invalid sequence.
35044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath      return false;
36044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath    } else {
37044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath      // 2-5 byte sequences.
38044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath      for (uint8_t first = byte << 1; first & 0x80; first <<= 1) {
39044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath        ++i;
40044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath
41044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath        // Missing continuation byte..
42044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath        if (i == length) {
43044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath          return false;
44044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath        }
45044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath
46044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath        // Invalid continuation byte.
47044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath        const uint8_t continuation_byte = entry_name[i];
48044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath        if ((continuation_byte & 0xc0) != 0x80) {
49044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath          return false;
50044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath        }
51044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath      }
52044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath    }
53044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath  }
54044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath
55044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath  return true;
56044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath}
57044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath
58044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath
59044bc8ee89462206dbf5f33c0573834ee507c955Narayan Kamath#endif  // LIBZIPARCHIVE_ENTRY_NAME_UTILS_INL_H_
60