Bug Summary

File:jvmfwk/plugins/sunmajor/pluginlib/sunversion.cxx
Location:line 59, column 36
Description:Null pointer passed as an argument to a 'nonnull' parameter

Annotated Source Code

1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20
21#include "sunversion.hxx"
22#include "osl/thread.h"
23#include "osl/process.h"
24#include "osl/security.hxx"
25#include <string.h>
26#include <ctype.h>
27#include "diagnostics.h"
28using namespace osl;
29
30using ::rtl::OUString;
31using ::rtl::OUStringToOString;
32using ::rtl::OString;
33namespace jfw_plugin { //stoc_javadetect
34
35
36#define OUSTR( x )::rtl::OUString((&(x)[0]), ((sal_Int32)((sizeof (x) / sizeof
((x)[0]))-1)), (((rtl_TextEncoding) 11)))
::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( x )(&(x)[0]), ((sal_Int32)((sizeof (x) / sizeof ((x)[0]))-1)
), (((rtl_TextEncoding) 11))
)
37
38#if OSL_DEBUG_LEVEL1 >= 2
39class SelfTest
40{
41public:
42 SelfTest();
43} test;
44#endif
45
46SunVersion::SunVersion(const rtl::OUString &usVer):
47 m_nUpdateSpecial(0), m_preRelease(Rel_NONE),
48 usVersion(usVer)
49{
50 memset(m_arVersionParts, 0, sizeof(m_arVersionParts));
51 rtl::OString sVersion= rtl::OUStringToOString(usVer, osl_getThreadTextEncoding());
52 m_bValid = init(sVersion.getStr());
53}
54SunVersion::SunVersion(const char * szVer):
55 m_nUpdateSpecial(0), m_preRelease(Rel_NONE)
56{
57 memset(m_arVersionParts, 0, sizeof(m_arVersionParts));
58 m_bValid = init(szVer);
1
Calling 'init'
3
Returning from 'init'
59 usVersion= rtl::OUString(szVer,strlen(szVer),osl_getThreadTextEncoding());
4
Null pointer passed as an argument to a 'nonnull' parameter
60}
61
62
63/**Format major.minor.maintainance_update
64 */
65bool SunVersion::init(const char *szVersion)
66{
67 if ( ! szVersion || strlen(szVersion) == 0)
2
Assuming pointer value is null
68 return false;
69
70 //first get the major,minor,maintainance
71 const char * pLast = szVersion;
72 const char * pCur = szVersion;
73 //pEnd point to the position after the last character
74 const char * pEnd = szVersion + strlen(szVersion);
75 // 0 = major, 1 = minor, 2 = maintainance, 3 = update
76 int nPart = 0;
77 // position within part beginning with 0
78 int nPartPos = 0;
79 char buf[128];
80
81 //char must me a number 0 - 999 and no leading
82 while (1)
83 {
84 if (pCur < pEnd && isdigit(*pCur))
85 {
86 if (pCur < pEnd)
87 pCur ++;
88 nPartPos ++;
89 }
90 //if correct separator then form integer
91 else if (
92 ! (nPartPos == 0) // prevents: ".4.1", "..1", part must start with digit
93 && (
94 //seperators after maintainance (1.4.1_01, 1.4.1-beta, or1.4.1
95 ((pCur == pEnd || *pCur == '_' || *pCur == '-') && (nPart == 2 ))
96 ||
97 //separators between major-minor and minor-maintainance
98 (nPart < 2 && *pCur == '.') )
99 && (
100 //prevent 1.4.0. 1.4.0-
101 pCur + 1 == pEnd ? isdigit(*(pCur)) : 1) )
102 {
103 int len = pCur - pLast;
104 if (len >= 127)
105 return false;
106
107 strncpy(buf, pLast, len);
108 buf[len] = 0;
109 pCur ++;
110 pLast = pCur;
111
112 m_arVersionParts[nPart] = atoi(buf);
113 nPart ++;
114 nPartPos = 0;
115 if (nPart == 3)
116 break;
117
118 //check next character
119 if (! ( (pCur < pEnd)
120 && ( (nPart < 3) && isdigit(*pCur))))
121 return false;
122 }
123 else
124 {
125 return false;
126 }
127 }
128 if (pCur >= pEnd)
129 return true;
130 //We have now 1.4.1. This can be followed by _01, -beta, etc.
131 // _01 (update) According to docu must not be followed by any other
132 //characters, but on Solaris 9 we have a 1.4.1_01a!!
133 if (* (pCur - 1) == '_')
134 {// _01, _02
135 // update is the last part _01, _01a, part 0 is the digits parts and 1 the trailing alpha
136 while (1)
137 {
138 if (pCur <= pEnd)
139 {
140 if ( ! isdigit(*pCur))
141 {
142 //1.4.1_01-, 1.4.1_01a, the numerical part may only be 2 chars.
143 int len = pCur - pLast;
144 if (len > 2)
145 return false;
146 //we've got the update: 01, 02 etc
147 strncpy(buf, pLast, len);
148 buf[len] = 0;
149 m_arVersionParts[nPart] = atoi(buf);
150 if (pCur == pEnd)
151 {
152 break;
153 }
154 if (*pCur == 'a' && (pCur + 1) == pEnd)
155 {
156 //check if it s followed by a simple "a" (not specified)
157 m_nUpdateSpecial = *pCur;
158 break;
159 }
160 else if (*pCur == '-' && pCur < pEnd)
161 {
162 //check 1.5.0_01-ea
163 PreRelease pr = getPreRelease(++pCur);
164 if (pr == Rel_NONE)
165 return false;
166 //just ignore -ea because its no official release
167 break;
168 }
169 else
170 {
171 return false;
172 }
173 }
174 if (pCur < pEnd)
175 pCur ++;
176 else
177 break;
178 }
179 }
180 }
181 // 1.4.1-ea
182 else if (*(pCur - 1) == '-')
183 {
184 m_preRelease = getPreRelease(pCur);
185 if (m_preRelease == Rel_NONE)
186 return false;
187#if defined(FREEBSD)
188 if (m_preRelease == Rel_FreeBSD)
189 {
190 pCur++; //elemnate `p'
191 if (pCur < pEnd && isdigit(*pCur))
192 pCur ++;
193 int len = pCur - pLast -1; //elemenate `p'
194 if (len >= 127)
195 return false;
196 strncpy(buf, (pLast+1), len); //elemenate `p'
197 buf[len] = 0;
198 m_nUpdateSpecial = atoi(buf)+100; //hack for FBSD #i56953#
199 return true;
200 }
201#endif
202 }
203 else
204 {
205 return false;
206 }
207 return true;
208}
209
210SunVersion::PreRelease SunVersion::getPreRelease(const char *szRelease)
211{
212 if (szRelease == NULL__null)
213 return Rel_NONE;
214 if( ! strcmp(szRelease,"ea"))
215 return Rel_EA;
216 else if( ! strcmp(szRelease,"ea1"))
217 return Rel_EA1;
218 else if( ! strcmp(szRelease,"ea2"))
219 return Rel_EA2;
220 else if( ! strcmp(szRelease,"ea3"))
221 return Rel_EA3;
222 else if ( ! strcmp(szRelease,"beta"))
223 return Rel_BETA;
224 else if ( ! strcmp(szRelease,"beta1"))
225 return Rel_BETA1;
226 else if ( ! strcmp(szRelease,"beta2"))
227 return Rel_BETA2;
228 else if ( ! strcmp(szRelease,"beta3"))
229 return Rel_BETA3;
230 else if (! strcmp(szRelease, "rc"))
231 return Rel_RC;
232 else if (! strcmp(szRelease, "rc1"))
233 return Rel_RC1;
234 else if (! strcmp(szRelease, "rc2"))
235 return Rel_RC2;
236 else if (! strcmp(szRelease, "rc3"))
237 return Rel_RC3;
238#if defined (FREEBSD)
239 else if (! strncmp(szRelease, "p", 1))
240 return Rel_FreeBSD;
241#endif
242 else
243 return Rel_NONE;
244}
245
246SunVersion::~SunVersion()
247{
248
249}
250
251/* Examples:
252 a) 1.0 < 1.1
253 b) 1.0 < 1.0.0
254 c) 1.0 < 1.0_00
255
256 returns false if both values are equal
257*/
258bool SunVersion::operator > (const SunVersion& ver) const
259{
260 if( &ver == this)
261 return false;
262
263 //compare major.minor.maintainance
264 for( int i= 0; i < 4; i ++)
265 {
266 // 1.4 > 1.3
267 if(m_arVersionParts[i] > ver.m_arVersionParts[i])
268 {
269 return true;
270 }
271 else if (m_arVersionParts[i] < ver.m_arVersionParts[i])
272 {
273 return false;
274 }
275 }
276 //major.minor.maintainance_update are equal. test for a trailing char
277 if (m_nUpdateSpecial > ver.m_nUpdateSpecial)
278 {
279 return true;
280 }
281
282 //Until here the versions are equal
283 //compare pre -release values
284 if ((m_preRelease == Rel_NONE && ver.m_preRelease == Rel_NONE)
285 ||
286 (m_preRelease != Rel_NONE && ver.m_preRelease == Rel_NONE))
287 return false;
288 else if (m_preRelease == Rel_NONE && ver.m_preRelease != Rel_NONE)
289 return true;
290 else if (m_preRelease > ver.m_preRelease)
291 return true;
292
293 return false;
294}
295
296bool SunVersion::operator < (const SunVersion& ver) const
297{
298 return (! operator > (ver)) && (! operator == (ver));
299}
300
301bool SunVersion::operator == (const SunVersion& ver) const
302{
303 bool bRet= true;
304 for(int i= 0; i < 4; i++)
305 {
306 if( m_arVersionParts[i] != ver.m_arVersionParts[i])
307 {
308 bRet= false;
309 break;
310 }
311 }
312 bRet = m_nUpdateSpecial == ver.m_nUpdateSpecial && bRet;
313 bRet = m_preRelease == ver.m_preRelease && bRet;
314 return bRet;
315}
316
317SunVersion::operator bool()
318{
319 return m_bValid;
320}
321
322#if OSL_DEBUG_LEVEL1 >= 2
323SelfTest::SelfTest()
324{
325 bool bRet = true;
326
327 char const * versions[] = {"1.4.0", "1.4.1", "1.0.0", "10.0.0", "10.10.0",
328 "10.2.2", "10.10.0", "10.10.10", "111.0.999",
329 "1.4.1_01", "9.90.99_09", "1.4.1_99",
330 "1.4.1_00a",
331 "1.4.1-ea", "1.4.1-beta", "1.4.1-rc1",
332 "1.5.0_01-ea", "1.5.0_01-rc2"};
333 char const * badVersions[] = {".4.0", "..1", "", "10.0", "10.10.0.", "10.10.0-", "10.10.0.",
334 "10.2-2", "10_10.0", "10..10","10.10", "a.0.999",
335 "1.4b.1_01", "9.90.-99_09", "1.4.1_99-",
336 "1.4.1_00a2", "1.4.0_z01z", "1.4.1__99A",
337 "1.4.1-1ea", "1.5.0_010", "1.5.0._01-", "1.5.0_01-eac"};
338 char const * orderedVer[] = { "1.3.1-ea", "1.3.1-beta", "1.3.1-rc1",
339 "1.3.1", "1.3.1_00a", "1.3.1_01", "1.3.1_01a",
340 "1.3.2", "1.4.0", "1.5.0_01-ea", "2.0.0"};
341
342 int num = sizeof (versions) / sizeof(char*);
343 int numBad = sizeof (badVersions) / sizeof(char*);
344 int numOrdered = sizeof (orderedVer) / sizeof(char*);
345 //parsing test (positive)
346 for (int i = 0; i < num; i++)
347 {
348 SunVersion ver(versions[i]);
349 if ( ! ver)
350 {
351 bRet = false;
352 break;
353 }
354 }
355 OSL_ENSURE(bRet, "SunVersion selftest failed")do { if (true && (!(bRet))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/usr/local/src/libreoffice/jvmfwk/plugins/sunmajor/pluginlib/sunversion.cxx"
":" "355" ": "), "%s", "SunVersion selftest failed"); } } while
(false)
;
356 //Parsing test (negative)
357 for ( int i = 0; i < numBad; i++)
358 {
359 SunVersion ver(badVersions[i]);
360 if (ver)
361 {
362 bRet = false;
363 break;
364 }
365 }
366 OSL_ENSURE(bRet, "SunVersion selftest failed")do { if (true && (!(bRet))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/usr/local/src/libreoffice/jvmfwk/plugins/sunmajor/pluginlib/sunversion.cxx"
":" "366" ": "), "%s", "SunVersion selftest failed"); } } while
(false)
;
367
368 // Ordering test
369 bRet = true;
370 int j = 0;
371 for (int i = 0; i < numOrdered; i ++)
372 {
373 SunVersion curVer(orderedVer[i]);
374 if ( ! curVer)
375 {
376 bRet = false;
377 break;
378 }
379 for (j = 0; j < numOrdered; j++)
380 {
381 SunVersion compVer(orderedVer[j]);
382 if (i < j)
383 {
384 if ( !(curVer < compVer))
385 {
386 bRet = false;
387 break;
388 }
389 }
390 else if ( i == j)
391 {
392 if (! (curVer == compVer
393 && ! (curVer > compVer)
394 && ! (curVer < compVer)))
395 {
396 bRet = false;
397 break;
398 }
399 }
400 else if (i > j)
401 {
402 if ( !(curVer > compVer))
403 {
404 bRet = false;
405 break;
406 }
407 }
408 }
409 if ( ! bRet)
410 break;
411 }
412 if (bRet)
413 JFW_TRACE2("[Java framework] sunjavaplugin: Testing class SunVersion succeeded.\n")do { if (true) { if (sizeof ::sal::detail::getResult( ::sal::
detail::StreamStart() << "[Java framework] sunjavaplugin: Testing class SunVersion succeeded.\n"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("jfw.level2"
), ("/usr/local/src/libreoffice/jvmfwk/plugins/sunmajor/pluginlib/sunversion.cxx"
":" "413" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "[Java framework] sunjavaplugin: Testing class SunVersion succeeded.\n"
)); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "[Java framework] sunjavaplugin: Testing class SunVersion succeeded.\n"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("jfw.level2"
), ("/usr/local/src/libreoffice/jvmfwk/plugins/sunmajor/pluginlib/sunversion.cxx"
":" "413" ": "), sal_detail_stream); } } } while (false)
;
414 else
415 OSL_ENSURE(bRet, "[Java framework] sunjavaplugin: SunVersion self test failed.\n")do { if (true && (!(bRet))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/usr/local/src/libreoffice/jvmfwk/plugins/sunmajor/pluginlib/sunversion.cxx"
":" "415" ": "), "%s", "[Java framework] sunjavaplugin: SunVersion self test failed.\n"
); } } while (false)
;
416}
417#endif
418
419}
420
421/* vim:set shiftwidth=4 softtabstop=4 expandtab: */