View Javadoc
1   /*
2     (C) Copyright IBM Corp. 2006, 2012
3   
4     THIS FILE IS PROVIDED UNDER THE TERMS OF THE ECLIPSE PUBLIC LICENSE
5     ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE
6     CONSTITUTES RECIPIENTS ACCEPTANCE OF THE AGREEMENT.
7   
8     You can obtain a current copy of the Eclipse Public License from
9     http://www.opensource.org/licenses/eclipse-1.0.php
10  
11    @author : Endre Bak, ebak@de.ibm.com
12   * 
13   * Flag       Date        Prog         Description
14   * -------------------------------------------------------------------------------
15   * 1565892    2006-11-05  ebak         Make SBLIM client JSR48 compliant
16   * 2003590    2008-06-30  blaschke-oss Change licensing from CPL to EPL
17   * 2524131    2009-01-21  raman_arora  Upgrade client to JDK 1.5 (Phase 1)
18   * 3572993    2012-10-01  blaschke-oss parseDouble("2.2250738585072012e-308") DoS vulnerability
19   */
20  
21  package org.metricshub.wbem.sblim.cimclient.internal.uri;
22  
23  /*-
24   * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲
25   * WBEM Java Client
26   * ჻჻჻჻჻჻
27   * Copyright 2023 - 2025 MetricsHub
28   * ჻჻჻჻჻჻
29   * Licensed under the Apache License, Version 2.0 (the "License");
30   * you may not use this file except in compliance with the License.
31   * You may obtain a copy of the License at
32   *
33   *      http://www.apache.org/licenses/LICENSE-2.0
34   *
35   * Unless required by applicable law or agreed to in writing, software
36   * distributed under the License is distributed on an "AS IS" BASIS,
37   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
38   * See the License for the specific language governing permissions and
39   * limitations under the License.
40   * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱
41   */
42  
43  import java.util.regex.Matcher;
44  import java.util.regex.Pattern;
45  import org.metricshub.wbem.sblim.cimclient.internal.util.MOF;
46  import org.metricshub.wbem.sblim.cimclient.internal.util.Util;
47  import org.metricshub.wbem.sblim.cimclient.internal.util.WBEMConfiguration;
48  
49  /**
50   * Class RealValue parses and encapsulates real values.
51   */
52  public class RealValue extends Value {
53  	private double iValue;
54  
55  	private boolean iDoublePrec;
56  
57  	private static final Pattern WHITE_PAT = Pattern.compile("^.*[\\s\\n]+.*$");
58  
59  	/**
60  	 * realValue = [ "+" | "-" ] *decimalDigit "." 1*decimalDigit [ ( "e" | "E"
61  	 * ) [ "+" | "-" ] 1*decimalDigit ] parse
62  	 *
63  	 * @param pUriStr
64  	 * @param pDoublePrec
65  	 * @return Value
66  	 */
67  	private static Value parse(URIString pUriStr, boolean pDoublePrec, boolean pThrow) throws IllegalArgumentException {
68  		URIString uriStr = pUriStr.deepCopy();
69  		// get the substring till the next ',' or end of pUriStr
70  		String strVal = uriStr.removeTill(',');
71  		if (strVal == null) {
72  			if (pThrow) {
73  				String msg = "Empty real value!\n" + uriStr.markPosition();
74  				throw new IllegalArgumentException(msg);
75  			}
76  			return null;
77  		}
78  		// strVal shouldn't contain white spaces
79  		Matcher m = WHITE_PAT.matcher(strVal);
80  		if (m.matches()) {
81  			if (pThrow) {
82  				String msg = "Illegal real format!\n" + pUriStr.markPosition();
83  				throw new IllegalArgumentException(msg);
84  			}
85  			return null;
86  		}
87  		try {
88  			if (WBEMConfiguration.getGlobalConfiguration().verifyJavaLangDoubleStrings()) {
89  				if (Util.isBadDoubleString(strVal)) throw new IllegalArgumentException(
90  					"Double value string hangs older JVMs!\n" + pUriStr.markPosition()
91  				);
92  			}
93  			double val = Double.parseDouble(strVal);
94  			pUriStr.set(uriStr);
95  			return new RealValue(val, pDoublePrec);
96  		} catch (NumberFormatException e) {
97  			if (pThrow) {
98  				String msg = "Illegal number format!\n" + pUriStr.markPosition() + "Nested message:\n" + e.getMessage();
99  				throw new IllegalArgumentException(msg);
100 			}
101 			return null;
102 		}
103 	}
104 
105 	/**
106 	 * Parses a RealValue as a double precision value.
107 	 *
108 	 * @param pUriStr
109 	 * @return Value
110 	 */
111 	public static Value parse(URIString pUriStr) {
112 		return parse(pUriStr, true, false);
113 	}
114 
115 	/**
116 	 * parseFloat
117 	 *
118 	 * @param pUriStr
119 	 * @return Value
120 	 * @throws IllegalArgumentException
121 	 *             if parsing failed
122 	 */
123 	public static Value parseFloat(URIString pUriStr) throws IllegalArgumentException {
124 		return parse(pUriStr, false, true);
125 	}
126 
127 	/**
128 	 * parseDouble
129 	 *
130 	 * @param pUriStr
131 	 * @return Value
132 	 * @throws IllegalArgumentException
133 	 *             if parsing failed
134 	 */
135 	public static Value parseDouble(URIString pUriStr) throws IllegalArgumentException {
136 		return parse(pUriStr, true, true);
137 	}
138 
139 	private RealValue(double pValue, boolean pDoublePrec) {
140 		this.iValue = pValue;
141 		this.iDoublePrec = pDoublePrec;
142 	}
143 
144 	/**
145 	 * isDouble
146 	 *
147 	 * @return boolean
148 	 */
149 	public boolean isDouble() {
150 		return this.iDoublePrec;
151 	}
152 
153 	/**
154 	 * floatValue
155 	 *
156 	 * @return float
157 	 */
158 	public float floatValue() {
159 		return (float) this.iValue;
160 	}
161 
162 	/**
163 	 * doubleValue
164 	 *
165 	 * @return double
166 	 */
167 	public double doubleValue() {
168 		return this.iValue;
169 	}
170 
171 	/**
172 	 * @see java.lang.Object#toString()
173 	 */
174 	@Override
175 	public String toString() {
176 		return Double.toString(this.iValue);
177 	}
178 
179 	/**
180 	 * @see Value#getTypeInfo()
181 	 */
182 	@Override
183 	public String getTypeInfo() {
184 		if (this.iDoublePrec) return MOF.DT_REAL64;
185 		return MOF.DT_REAL32;
186 	}
187 }