source: josm/trunk/src/org/openstreetmap/josm/data/validation/routines/InetAddressValidator.java@ 12867

Last change on this file since 12867 was 11930, checked in by Don-vip, 7 years ago

PMD - enable subset of optimizations rules

  • Property svn:eol-style set to native
File size: 6.6 KB
Line 
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17package org.openstreetmap.josm.data.validation.routines;
18
19import java.util.ArrayList;
20import java.util.Arrays;
21import java.util.List;
22
23/**
24 * <p><b>InetAddress</b> validation and conversion routines (<code>java.net.InetAddress</code>).</p>
25 *
26 * <p>This class provides methods to validate a candidate IP address.
27 *
28 * <p>
29 * This class is a Singleton; you can retrieve the instance via the {@link #getInstance()} method.
30 * </p>
31 *
32 * @version $Revision: 1741724 $
33 * @since Validator 1.4
34 */
35public class InetAddressValidator extends AbstractValidator {
36
37 private static final int IPV4_MAX_OCTET_VALUE = 255;
38
39 private static final int MAX_UNSIGNED_SHORT = 0xffff;
40
41 private static final int BASE_16 = 16;
42
43 private static final String IPV4_REGEX =
44 "^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$";
45
46 // Max number of hex groups (separated by :) in an IPV6 address
47 private static final int IPV6_MAX_HEX_GROUPS = 8;
48
49 // Max hex digits in each IPv6 group
50 private static final int IPV6_MAX_HEX_DIGITS_PER_GROUP = 4;
51
52 /**
53 * Singleton instance of this class.
54 */
55 private static final InetAddressValidator VALIDATOR = new InetAddressValidator();
56
57 /** IPv4 RegexValidator */
58 private final RegexValidator ipv4Validator = new RegexValidator(IPV4_REGEX);
59
60 /**
61 * Returns the singleton instance of this validator.
62 * @return the singleton instance of this validator
63 */
64 public static InetAddressValidator getInstance() {
65 return VALIDATOR;
66 }
67
68 /**
69 * Checks if the specified string is a valid IP address.
70 * @param inetAddress the string to validate
71 * @return true if the string validates as an IP address
72 */
73 @Override
74 public boolean isValid(String inetAddress) {
75 return isValidInet4Address(inetAddress) || isValidInet6Address(inetAddress);
76 }
77
78 @Override
79 public String getValidatorName() {
80 return null;
81 }
82
83 /**
84 * Validates an IPv4 address. Returns true if valid.
85 * @param inet4Address the IPv4 address to validate
86 * @return true if the argument contains a valid IPv4 address
87 */
88 public boolean isValidInet4Address(String inet4Address) {
89 // verify that address conforms to generic IPv4 format
90 String[] groups = ipv4Validator.match(inet4Address);
91
92 if (groups == null) {
93 return false;
94 }
95
96 // verify that address subgroups are legal
97 for (String ipSegment : groups) {
98 if (ipSegment == null || ipSegment.isEmpty()) {
99 return false;
100 }
101
102 int iIpSegment = 0;
103
104 try {
105 iIpSegment = Integer.parseInt(ipSegment);
106 } catch (NumberFormatException e) {
107 return false;
108 }
109
110 if (iIpSegment > IPV4_MAX_OCTET_VALUE) {
111 return false;
112 }
113
114 if (ipSegment.length() > 1 && ipSegment.startsWith("0")) {
115 return false;
116 }
117
118 }
119
120 return true;
121 }
122
123 /**
124 * Validates an IPv6 address. Returns true if valid.
125 * @param inet6Address the IPv6 address to validate
126 * @return true if the argument contains a valid IPv6 address
127 *
128 * @since 1.4.1
129 */
130 public boolean isValidInet6Address(String inet6Address) {
131 boolean containsCompressedZeroes = inet6Address.contains("::");
132 if (containsCompressedZeroes && (inet6Address.indexOf("::") != inet6Address.lastIndexOf("::"))) {
133 return false;
134 }
135 if ((inet6Address.startsWith(":") && !inet6Address.startsWith("::"))
136 || (inet6Address.endsWith(":") && !inet6Address.endsWith("::"))) {
137 return false;
138 }
139 String[] octets = inet6Address.split(":");
140 if (containsCompressedZeroes) {
141 List<String> octetList = new ArrayList<>(Arrays.asList(octets));
142 if (inet6Address.endsWith("::")) {
143 // String.split() drops ending empty segments
144 octetList.add("");
145 } else if (inet6Address.startsWith("::") && !octetList.isEmpty()) {
146 octetList.remove(0);
147 }
148 octets = octetList.toArray(new String[octetList.size()]);
149 }
150 if (octets.length > IPV6_MAX_HEX_GROUPS) {
151 return false;
152 }
153 int validOctets = 0;
154 int emptyOctets = 0;
155 for (int index = 0; index < octets.length; index++) {
156 String octet = octets[index];
157 if (octet.length() == 0) {
158 emptyOctets++;
159 if (emptyOctets > 1) {
160 return false;
161 }
162 } else {
163 emptyOctets = 0;
164 if (octet.contains(".")) { // contains is Java 1.5+
165 if (!inet6Address.endsWith(octet)) {
166 return false;
167 }
168 if (index > octets.length - 1 || index > 6) { // CHECKSTYLE IGNORE MagicNumber
169 // IPV4 occupies last two octets
170 return false;
171 }
172 if (!isValidInet4Address(octet)) {
173 return false;
174 }
175 validOctets += 2;
176 continue;
177 }
178 if (octet.length() > IPV6_MAX_HEX_DIGITS_PER_GROUP) {
179 return false;
180 }
181 int octetInt = 0;
182 try {
183 octetInt = Integer.parseInt(octet, BASE_16);
184 } catch (NumberFormatException e) {
185 return false;
186 }
187 if (octetInt < 0 || octetInt > MAX_UNSIGNED_SHORT) {
188 return false;
189 }
190 }
191 validOctets++;
192 }
193 return validOctets >= IPV6_MAX_HEX_GROUPS || containsCompressedZeroes;
194 }
195}
Note: See TracBrowser for help on using the repository browser.