Bug Summary

File:sal/rtl/source/locale.cxx
Location:line 160, column 9
Description:Access to field 'Next' results in a dereference of a null pointer (loaded from variable 'pEntry')

Annotated Source Code

1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*************************************************************************
3 *
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 *
8 * OpenOffice.org - a multi-platform office productivity suite
9 *
10 * This file is part of OpenOffice.org.
11 *
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
15 *
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
21 *
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
26 *
27 ************************************************************************/
28
29#include "rtl/locale.h"
30
31#include "osl/diagnose.h"
32#include "rtl/alloc.h"
33
34#include "internal/rtllifecycle.h"
35
36static sal_Int32 RTL_HASHTABLE_SIZE[] =
37{
38 7, 31, 127, 251, 509, 1021, 2039, 4093
39};
40
41struct RTL_HASHENTRY
42{
43 rtl_Locale* Entry;
44 RTL_HASHENTRY* Next;
45};
46
47struct RTL_HASHTABLE
48{
49 sal_Int8 iSize;
50 sal_Int32 Size;
51 sal_Int32 Elements;
52 RTL_HASHENTRY** Table;
53};
54
55static RTL_HASHTABLE* g_pLocaleTable = NULL__null;
56
57static rtl_Locale* g_pDefaultLocale = NULL__null;
58
59/*************************************************************************
60 */
61extern "C" void rtl_hashentry_destroy(RTL_HASHENTRY* entry)
62{
63 rtl_uString_release(entry->Entry->Language);
64 rtl_uString_release(entry->Entry->Country);
65 rtl_uString_release(entry->Entry->Variant);
66 if (entry->Next)
67 rtl_hashentry_destroy(entry->Next);
68
69 rtl_freeMemory(entry->Entry);
70 rtl_freeMemory(entry);
71}
72
73extern "C" void rtl_hashtable_destroy(RTL_HASHTABLE* table)
74{
75 sal_Int32 size = 0;
76
77 if (!table)
78 return;
79
80 size = table->Size;
81
82 while (size)
83 {
84 if (table->Table[size - 1])
85 rtl_hashentry_destroy(table->Table[size - 1]);
86 size--;
87 }
88
89 rtl_freeMemory(table->Table);
90 rtl_freeMemory(table);
91}
92
93extern "C" void rtl_hashtable_init(RTL_HASHTABLE** table, sal_Int8 sizeIndex)
94{
95 sal_Int32 nSize = RTL_HASHTABLE_SIZE[sizeIndex];
96
97 if (*table)
98 rtl_hashtable_destroy(*table);
99
100 *table = (RTL_HASHTABLE*)rtl_allocateMemory( sizeof(RTL_HASHTABLE) );
101
102 (*table)->iSize = sizeIndex;
103 (*table)->Size = nSize;
104 (*table)->Elements = 0;
105 (*table)->Table = (RTL_HASHENTRY**)rtl_allocateMemory( (*table)->Size * sizeof(RTL_HASHENTRY*) );
106
107 while (nSize)
108 {
109 (*table)->Table[nSize - 1] = NULL__null;
110 nSize--;
111 }
112}
113
114extern "C" sal_Int32 rtl_hashfunc(RTL_HASHTABLE* table, sal_Int32 key)
115{
116 return ( (sal_uInt32) key % table->Size);
117}
118
119extern "C" sal_Bool rtl_hashtable_grow(RTL_HASHTABLE** table);
120
121extern "C" rtl_Locale* rtl_hashtable_add(RTL_HASHTABLE** table, rtl_Locale* value)
122{
123 sal_Int32 key = 0;
124
125 if (!(*table))
7
Taking false branch
126 return NULL__null;
127
128 if ((*table)->Elements > ((*table)->Size / 2))
8
Taking false branch
129 rtl_hashtable_grow(table);
130
131 key = rtl_hashfunc(*table, value->HashCode);
132
133 if (!(*table)->Table[key])
9
Taking false branch
134 {
135 RTL_HASHENTRY *newEntry = (RTL_HASHENTRY*)rtl_allocateMemory( sizeof(RTL_HASHENTRY) );
136 newEntry->Entry = value;
137 newEntry->Next = NULL__null;
138 (*table)->Table[key] = newEntry;
139 (*table)->Elements++;
140 return NULL__null;
141 } else
142 {
143 RTL_HASHENTRY *pEntry = (*table)->Table[key];
10
Variable 'pEntry' initialized here
144 RTL_HASHENTRY *newEntry = NULL__null;
145
146 while (pEntry)
11
Loop condition is false. Execution continues on line 157
147 {
148 if (value->HashCode == pEntry->Entry->HashCode)
149 return pEntry->Entry;
150
151 if (!pEntry->Next)
152 break;
153
154 pEntry = pEntry->Next;
155 }
156
157 newEntry = (RTL_HASHENTRY*)rtl_allocateMemory( sizeof(RTL_HASHENTRY) );
158 newEntry->Entry = value;
159 newEntry->Next = NULL__null;
160 pEntry->Next = newEntry;
12
Access to field 'Next' results in a dereference of a null pointer (loaded from variable 'pEntry')
161 (*table)->Elements++;
162 return NULL__null;
163 }
164}
165
166sal_Bool rtl_hashtable_grow(RTL_HASHTABLE** table)
167{
168 RTL_HASHTABLE* pNewTable = NULL__null;
169 sal_Int32 i = 0;
170
171 rtl_hashtable_init(&pNewTable, (sal_Int8)((*table)->iSize + 1));
172
173 while (i < (*table)->Size)
174 {
175 if ((*table)->Table[i])
176 {
177 RTL_HASHENTRY *pNext;
178 RTL_HASHENTRY *pEntry = (*table)->Table[i];
179
180 rtl_hashtable_add(&pNewTable, pEntry->Entry);
181
182 while (pEntry->Next)
183 {
184 rtl_hashtable_add(&pNewTable, pEntry->Next->Entry);
185 pNext = pEntry->Next;
186 rtl_freeMemory(pEntry);
187 pEntry = pNext;
188 }
189
190 rtl_freeMemory(pEntry);
191 }
192 i++;
193 }
194
195 rtl_freeMemory((*table)->Table);
196 rtl_freeMemory((*table));
197 (*table) = pNewTable;
198
199 return sal_True((sal_Bool)1);
200}
201
202extern "C" sal_Bool rtl_hashtable_find(RTL_HASHTABLE * table, sal_Int32 key, sal_Int32 hashCode, rtl_Locale** pValue)
203{
204 if (!table)
205 return sal_False((sal_Bool)0);
206
207 if (table->Table[key])
208 {
209 RTL_HASHENTRY *pEntry = table->Table[key];
210
211 while (pEntry && hashCode != pEntry->Entry->HashCode)
212 pEntry = pEntry->Next;
213
214 if (pEntry)
215 *pValue = pEntry->Entry;
216 else
217 return sal_False((sal_Bool)0);
218 } else
219 return sal_False((sal_Bool)0);
220
221 return sal_True((sal_Bool)1);
222}
223
224/*************************************************************************
225 * rtl_locale_init
226 */
227void rtl_locale_init()
228{
229 OSL_ASSERT(g_pLocaleTable == 0)do { if (true && (!(g_pLocaleTable == 0))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/rtl/source/locale.cxx"
":" "229" ": "), "OSL_ASSERT: %s", "g_pLocaleTable == 0"); }
} while (false)
;
230 rtl_hashtable_init(&g_pLocaleTable, 1);
231}
232
233/*************************************************************************
234 * rtl_locale_fini
235 */
236void rtl_locale_fini()
237{
238 if (g_pLocaleTable != 0)
239 {
240 rtl_hashtable_destroy (g_pLocaleTable);
241 g_pLocaleTable = 0;
242 }
243}
244
245/*************************************************************************
246 * rtl_locale_register
247 */
248rtl_Locale * SAL_CALL rtl_locale_register( const sal_Unicode * language, const sal_Unicode * country, const sal_Unicode * variant )
249{
250 sal_Unicode c = 0;
251 rtl_uString* sLanguage = NULL__null;
252 rtl_uString* sCountry = NULL__null;
253 rtl_uString* sVariant = NULL__null;
254 rtl_Locale *newLocale = NULL__null;
255 sal_Int32 hashCode = -1;
256 sal_Int32 key = 0;
257
258 if ( !country )
2
Taking false branch
259 country = &c;
260 if ( !variant )
3
Taking false branch
261 variant = &c;
262
263 ensureLocaleSingleton();
264 if (!g_pLocaleTable)
4
Taking false branch
265 return NULL__null;
266
267 hashCode = rtl_ustr_hashCode(language) ^ rtl_ustr_hashCode(country) ^ rtl_ustr_hashCode(variant);
268 key = rtl_hashfunc(g_pLocaleTable, hashCode);
269
270 if (rtl_hashtable_find(g_pLocaleTable, key, hashCode, &newLocale))
5
Taking false branch
271 return newLocale;
272
273 rtl_uString_newFromStr(&sLanguage, language);
274 rtl_uString_newFromStr(&sCountry, country);
275 rtl_uString_newFromStr(&sVariant, variant);
276
277 newLocale = (rtl_Locale*)rtl_allocateMemory( sizeof(rtl_Locale) );
278
279 newLocale->Language = sLanguage;
280 newLocale->Country = sCountry;
281 newLocale->Variant = sVariant;
282 newLocale->HashCode = hashCode;
283
284 rtl_hashtable_add(&g_pLocaleTable, newLocale);
6
Calling 'rtl_hashtable_add'
285
286 return newLocale;
287}
288
289/*************************************************************************
290 * rtl_locale_getDefault
291 */
292rtl_Locale * SAL_CALL rtl_locale_getDefault()
293{
294 return g_pDefaultLocale;
295}
296
297/*************************************************************************
298 * rtl_locale_setDefault
299 */
300void SAL_CALL rtl_locale_setDefault( const sal_Unicode * language, const sal_Unicode * country, const sal_Unicode * variant )
301{
302 g_pDefaultLocale = rtl_locale_register(language, country, variant);
1
Calling 'rtl_locale_register'
303}
304
305/*************************************************************************
306 * rtl_locale_getLanguage
307 */
308rtl_uString * SAL_CALL rtl_locale_getLanguage( rtl_Locale * This )
309{
310 rtl_uString_acquire(This->Language);
311 return This->Language;
312}
313
314/*************************************************************************
315 * rtl_locale_getCountry
316 */
317rtl_uString * SAL_CALL rtl_locale_getCountry( rtl_Locale * This )
318{
319 rtl_uString_acquire(This->Country);
320 return This->Country;
321}
322
323/*************************************************************************
324 * rtl_locale_getVariant
325 */
326rtl_uString * SAL_CALL rtl_locale_getVariant( rtl_Locale * This )
327{
328 rtl_uString_acquire(This->Variant);
329 return This->Variant;
330}
331
332/*************************************************************************
333 * rtl_locale_hashCode
334 */
335sal_Int32 SAL_CALL rtl_locale_hashCode( rtl_Locale * This )
336{
337 return This->HashCode;
338}
339
340/*************************************************************************
341 * rtl_locale_equals
342 */
343sal_Int32 SAL_CALL rtl_locale_equals( rtl_Locale * This, rtl_Locale * obj )
344{
345 return This == obj;
346}
347
348/* vim:set shiftwidth=4 softtabstop=4 expandtab: */