View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.shared.resource;
20  
21  public class ResourceValidationUtils
22  {
23      public static boolean isValidResourceName(String resourceName)
24      {
25          return validateResourceName(resourceName, true);
26      }
27      
28      public static boolean isValidLibraryName(String libraryName)
29      {
30          return validate(libraryName, false);
31      }
32      
33      public static boolean isValidLibraryName(String libraryName, boolean allowSlash)
34      {
35          return validate(libraryName, allowSlash);
36      }
37      
38      public static boolean isValidResourceId(String resourceId)
39      {
40          // Follow the same rules as for resourceName, but check resourceId does not
41          // start with '/'
42          return resourceId.length() > 0 && resourceId.charAt(0) != '/' && 
43              validateResourceName(resourceId, true); 
44      }
45      
46      public static boolean isValidViewResource(String resourceId)
47      {
48          // Follow the same rules as for resourceName, but check resourceId does not
49          // start with '/'
50          return validateResourceName(resourceId, true);
51      }
52      
53      public static boolean isValidContractName(String contractName)
54      {
55          return validate(contractName, false);
56      }    
57      
58      public static boolean isValidLocalePrefix(String localePrefix)
59      {
60          for (int i = 0, length = localePrefix.length(); i < length; i++)
61          {
62              char c = localePrefix.charAt(i);
63              if ( (c >='A' && c <='Z') || c == '_' || (c >='a' && c <='z') || (c >='0' && c <='9') )
64              {
65                  continue;
66              }
67              else
68              {
69                  return false;
70              }
71          }
72          return true;
73      }
74      
75      private static boolean validate(String expression, boolean allowSlash)
76      {
77          int length = expression.length();
78          if (length == 2 && 
79              expression.charAt(0) == '.' &&
80              expression.charAt(1) == '.')
81          {
82              return false;
83          }
84          for (int i = 0; i < length; i++)
85          {
86              char c = expression.charAt(i);
87  
88              // Enforce NameChar convention as specified
89              // http://www.w3.org/TR/REC-xml/#NT-NameChar
90              // Valid characters for NameChar
91              // ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | 
92              // [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | 
93              // [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] 
94              // | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
95              // "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
96              // Excluding ":" 
97              if ( (c >='A' && c <='Z') || c == '_' || (c >='a' && c <='z') || 
98                   (c >=0xC0 && c <=0xD6) || (c >=0xD8 && c <=0xF6) || 
99                   (c >=0xF8 && c <=0x2FF) || (c >=0x370 && c <=0x37D) || 
100                  (c >=0x37F && c <=0x1FFF) || (c >=0x200C && c <=0x200D) ||
101                  (c >=0x2070 && c <=0x218F) || (c >=0x2C00 && c <=0x2FEF) || 
102                  (c >=0x3001 && c <=0xD7FF) || (c >=0xF900 && c <=0xFDCF) ||
103                  (c >=0xFDF0 && c <=0xFFFD) || (c >=0x10000 && c <=0xEFFFF) ||
104                  c == '-' || (c >='0' && c <='9') || c == 0xB7 || (c >=0x300 && c <=0x36F) || 
105                  (c >=0x203F && c <=0x2040) || (allowSlash && c == '/')
106                  )
107             {
108                 continue;
109             }
110             else if (c == '.')
111             {
112                 if (i+2 < length)
113                 {
114                     char c1 = expression.charAt(i+1);
115                     char c2 = expression.charAt(i+2);
116                     if (c == c1 && (c2 == '/' || c2 == '\\' ) )
117                     {
118                         return false;
119                     }
120                 }
121                 continue;
122             }
123             else
124             {
125                 return false;
126             }
127         }
128         if (length >= 3)
129         {
130             if ( (expression.charAt(length-3) == '/' || expression.charAt(length-3) == '\\' ) && 
131                   expression.charAt(length-2) == '.' &&
132                   expression.charAt(length-1) == '.' )
133             {
134                 return false;
135             }
136         }
137         return true;
138     }
139     
140     private static boolean validateResourceName(String expression, boolean allowSlash)
141     {
142         int length = expression.length();
143         if (length == 2 && 
144             expression.charAt(0) == '.' &&
145             expression.charAt(1) == '.')
146         {
147             return false;
148         }
149         for (int i = 0; i < length; i++)
150         {
151             char c = expression.charAt(i);
152 
153             // Enforce NameChar convention as specified
154             // http://www.w3.org/TR/REC-xml/#NT-NameChar
155             // Valid characters for NameChar
156             // ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | 
157             // [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | 
158             // [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] 
159             // | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
160             // "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
161             // Excluding ":" 
162             
163             // Forbidden chars by win
164             // < (less than)
165             // > (greater than)
166             // : (colon)
167             // " (double quote)
168             // / (forward slash)
169             // \ (backslash)
170             // | (vertical bar or pipe)
171             // ? (question mark)
172             // * (asterisk)
173             // Do not use chars in UNIX because they have special meaning
174             // *&%$|^/\~
175             if ( (c >='A' && c <='Z') || c == '_' || (c >='a' && c <='z') || 
176                  (c >=0xC0 && c <=0xD6) || (c >=0xD8 && c <=0xF6) || 
177                  (c >=0xF8 && c <=0x2FF) || (c >=0x370 && c <=0x37D) || 
178                  (c >=0x37F && c <=0x1FFF) || (c >=0x200C && c <=0x200D) ||
179                  (c >=0x2070 && c <=0x218F) || (c >=0x2C00 && c <=0x2FEF) || 
180                  (c >=0x3001 && c <=0xD7FF) || (c >=0xF900 && c <=0xFDCF) ||
181                  (c >=0xFDF0 && c <=0xFFFD) || (c >=0x10000 && c <=0xEFFFF) ||
182                  (c == '-') || (c >='0' && c <='9') || c == 0xB7 || (c >=0x300 && c <=0x36F) || 
183                  (c >=0x203F && c <=0x2040) || (allowSlash && c == '/') ||
184                  (c == '!') || (c == '#') || (c == '\'') || (c == '(') || (c == ')') ||
185                  (c == '+') || (c == ',') || (c == ';' ) || (c == '=') || 
186                  (c == '@') || (c == '[') || (c == ']' ) || (c == '{') || (c == '}'))
187             {
188                 continue;
189             }
190             else if (c == '.')
191             {
192                 if (i+2 < length)
193                 {
194                     char c1 = expression.charAt(i+1);
195                     char c2 = expression.charAt(i+2);
196                     if (c == c1 && (c2 == '/' || c2 == '\\' ) )
197                     {
198                         return false;
199                     }
200                 }
201                 continue;
202             }
203             else
204             {
205                 return false;
206             }
207         }
208         if (length >= 3)
209         {
210             if ( (expression.charAt(length-3) == '/' || expression.charAt(length-3) == '\\' ) && 
211                   expression.charAt(length-2) == '.' &&
212                   expression.charAt(length-1) == '.' )
213             {
214                 return false;
215             }
216         }
217         return true;
218     }
219 }