1 /*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "UidRanges.h"
18
19 #include "NetdConstants.h"
20
21 #include <stdlib.h>
22
hasUid(uid_t uid) const23 bool UidRanges::hasUid(uid_t uid) const {
24 auto iter = std::lower_bound(mRanges.begin(), mRanges.end(), Range(uid, uid));
25 return (iter != mRanges.end() && iter->first == uid) ||
26 (iter != mRanges.begin() && (--iter)->second >= uid);
27 }
28
getRanges() const29 const std::vector<UidRanges::Range>& UidRanges::getRanges() const {
30 return mRanges;
31 }
32
parseFrom(int argc,char * argv[])33 bool UidRanges::parseFrom(int argc, char* argv[]) {
34 mRanges.clear();
35 for (int i = 0; i < argc; ++i) {
36 if (!*argv[i]) {
37 // The UID string is empty.
38 return false;
39 }
40 char* endPtr;
41 uid_t uidStart = strtoul(argv[i], &endPtr, 0);
42 uid_t uidEnd;
43 if (!*endPtr) {
44 // Found a single UID. The range contains just the one UID.
45 uidEnd = uidStart;
46 } else if (*endPtr == '-') {
47 if (!*++endPtr) {
48 // Unexpected end of string.
49 return false;
50 }
51 uidEnd = strtoul(endPtr, &endPtr, 0);
52 if (*endPtr) {
53 // Illegal trailing chars.
54 return false;
55 }
56 if (uidEnd < uidStart) {
57 // Invalid order.
58 return false;
59 }
60 } else {
61 // Not a single uid, not a range. Found some other illegal char.
62 return false;
63 }
64 if (uidStart == INVALID_UID || uidEnd == INVALID_UID) {
65 // Invalid UIDs.
66 return false;
67 }
68 mRanges.push_back(Range(uidStart, uidEnd));
69 }
70 std::sort(mRanges.begin(), mRanges.end());
71 return true;
72 }
73
add(const UidRanges & other)74 void UidRanges::add(const UidRanges& other) {
75 auto middle = mRanges.insert(mRanges.end(), other.mRanges.begin(), other.mRanges.end());
76 std::inplace_merge(mRanges.begin(), middle, mRanges.end());
77 }
78
remove(const UidRanges & other)79 void UidRanges::remove(const UidRanges& other) {
80 auto end = std::set_difference(mRanges.begin(), mRanges.end(), other.mRanges.begin(),
81 other.mRanges.end(), mRanges.begin());
82 mRanges.erase(end, mRanges.end());
83 }
84