Bug Summary

File:home/maarten/src/libreoffice/core/vcl/unx/generic/print/glyphset.cxx
Warning:line 210, column 25
Assigned value is garbage or undefined

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name glyphset.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/glm -isystem /usr/include/glib-2.0 -isystem /usr/lib64/glib-2.0/include -isystem /usr/include/libmount -isystem /usr/include/blkid -isystem /usr/include/cairo -isystem /usr/include/glib-2.0 -isystem /usr/lib64/glib-2.0/include -isystem /usr/include/pixman-1 -isystem /usr/include/freetype2 -isystem /usr/include/libpng16 -isystem /usr/include/libxml2 -isystem /usr/include/freetype2 -isystem /usr/include/libpng16 -isystem /usr/include/dbus-1.0 -isystem /usr/lib64/dbus-1.0/include -isystem /usr/include/freetype2 -isystem /usr/include/libpng16 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D VCL_DLLIMPLEMENTATION -D DLLIMPLEMENTATION_UITEST -D CUI_DLL_NAME="libcuilo.so" -D DESKTOP_DETECTOR_DLL_NAME="libdesktop_detectorlo.so" -D TK_DLL_NAME="libtklo.so" -D SYSTEM_ZLIB -D GLM_FORCE_CTOR_INIT -D SK_USER_CONFIG_HEADER=</home/maarten/src/libreoffice/core/config_host/config_skia.h> -D SKIA_DLL -D ENABLE_CUPS -D HAVE_VALGRIND_HEADERS -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/epoxy/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/core -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/effects -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/gpu -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/config -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/ports -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/third_party/vulkan -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/tools/gpu -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia -I /home/maarten/src/libreoffice/core/external/skia/inc/ -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/mdds/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/lcms2/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/harfbuzz/src -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/graphite/include -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/pdfium -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/pdfium/public -D COMPONENT_BUILD -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/libpng -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/libjpeg-turbo -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/vcl/inc -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libxml2 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/vcl/unx/generic/print/glyphset.cxx
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#include "glyphset.hxx"
21
22#include <sft.hxx>
23
24#include <unx/printergfx.hxx>
25#include <fontsubset.hxx>
26#include <unx/fontmanager.hxx>
27
28#include <tools/gen.hxx>
29
30#include <osl/thread.h>
31
32#include <rtl/ustring.hxx>
33#include <rtl/strbuf.hxx>
34
35#include <unotools/tempfile.hxx>
36
37#include <algorithm>
38
39using namespace vcl;
40using namespace psp;
41
42GlyphSet::GlyphSet (sal_Int32 nFontID, bool bVertical)
43 : mnFontID (nFontID),
44 mbVertical (bVertical)
45{
46 PrintFontManager &rMgr = PrintFontManager::get();
47 maBaseName = OUStringToOString (rMgr.getPSName(mnFontID),
48 RTL_TEXTENCODING_ASCII_US(((rtl_TextEncoding) 11)));
49}
50
51void
52GlyphSet::GetGlyphID (
53 sal_GlyphId nGlyph,
54 unsigned char* nOutGlyphID,
55 sal_Int32* nOutGlyphSetID
56 )
57{
58 if (!LookupGlyphID(nGlyph, nOutGlyphID, nOutGlyphSetID))
59 AddGlyphID(nGlyph, nOutGlyphID, nOutGlyphSetID);
60}
61
62bool
63GlyphSet::LookupGlyphID (
64 sal_GlyphId nGlyph,
65 unsigned char* nOutGlyphID,
66 sal_Int32* nOutGlyphSetID
67 )
68{
69 sal_Int32 nGlyphSetID = 1;
70
71 // loop through all the font subsets
72 for (auto const& glyph : maGlyphList)
73 {
74 // check every subset if it contains the queried unicode char
75 glyph_map_t::const_iterator aGlyph = glyph.find (nGlyph);
76 if (aGlyph != glyph.end())
77 {
78 // success: found the glyph id, return the mapped glyphid and the glyphsetid
79 *nOutGlyphSetID = nGlyphSetID;
80 *nOutGlyphID = aGlyph->second;
81 return true;
82 }
83 ++nGlyphSetID;
84 }
85
86 *nOutGlyphSetID = -1;
87 *nOutGlyphID = 0;
88 return false;
89}
90
91void
92GlyphSet::AddNotdef (glyph_map_t &rGlyphMap)
93{
94 if (rGlyphMap.empty())
95 rGlyphMap[0] = 0;
96}
97
98void
99GlyphSet::AddGlyphID (
100 sal_GlyphId nGlyph,
101 unsigned char* nOutGlyphID,
102 sal_Int32* nOutGlyphSetID
103 )
104{
105 // create an empty glyphmap that is reserved for unencoded symbol glyphs,
106 // and a second map that takes any other
107 if (maGlyphList.empty())
108 {
109 glyph_map_t aMap, aMapp;
110
111 maGlyphList.push_back (aMap);
112 maGlyphList.push_back (aMapp);
113 }
114 // if the last map is full, create a new one
115 if (maGlyphList.back().size() == 255)
116 {
117 glyph_map_t aMap;
118 maGlyphList.push_back (aMap);
119 }
120
121 glyph_map_t& aGlyphSet = maGlyphList.back();
122 AddNotdef (aGlyphSet);
123
124 int nSize = aGlyphSet.size();
125
126 aGlyphSet [nGlyph] = nSize;
127 *nOutGlyphSetID = maGlyphList.size();
128 *nOutGlyphID = aGlyphSet [nGlyph];
129}
130
131OString
132GlyphSet::GetGlyphSetName (sal_Int32 nGlyphSetID)
133{
134 OStringBuffer aSetName( maBaseName.getLength() + 32 );
135 aSetName.append( maBaseName );
136 aSetName.append( "FID" );
137 aSetName.append( mnFontID );
138 aSetName.append( mbVertical ? "VGSet" : "HGSet" );
139 aSetName.append( nGlyphSetID );
140 return aSetName.makeStringAndClear();
141}
142
143OString
144GlyphSet::GetReencodedFontName (rtl_TextEncoding nEnc, const OString &rFontName)
145{
146 if ( nEnc == RTL_TEXTENCODING_MS_1252(((rtl_TextEncoding) 1))
147 || nEnc == RTL_TEXTENCODING_ISO_8859_1(((rtl_TextEncoding) 12)))
148 {
149 return rFontName + "-iso1252";
150 }
151 else
152 if (nEnc >= RTL_TEXTENCODING_USER_START(((rtl_TextEncoding) 0x8000)) && nEnc <= RTL_TEXTENCODING_USER_END(((rtl_TextEncoding) 0xEFFF)))
153 {
154 return rFontName
155 + "-enc"
156 + OString::number ((nEnc - RTL_TEXTENCODING_USER_START(((rtl_TextEncoding) 0x8000))));
157 }
158 else
159 {
160 return OString();
161 }
162}
163
164void GlyphSet::DrawGlyph(PrinterGfx& rGfx,
165 const Point& rPoint,
166 const sal_GlyphId nGlyphId)
167{
168 unsigned char nGlyphID;
169 sal_Int32 nGlyphSetID;
170
171 // convert to font glyph id and font subset
172 GetGlyphID (nGlyphId, &nGlyphID, &nGlyphSetID);
173
174 OString aGlyphSetName = GetGlyphSetName(nGlyphSetID);
175
176 rGfx.PSSetFont (aGlyphSetName, RTL_TEXTENCODING_DONTKNOW(((rtl_TextEncoding) 0)));
177 rGfx.PSMoveTo (rPoint);
178 rGfx.PSShowGlyph(nGlyphID);
179}
180
181namespace {
182
183struct EncEntry
184{
185 unsigned char aEnc;
186 long aGID;
187
188 EncEntry() : aEnc( 0 ), aGID( 0 ) {}
189
190 bool operator<( const EncEntry& rRight ) const
191 { return aEnc < rRight.aEnc; }
192};
193
194}
195
196static void CreatePSUploadableFont( TrueTypeFont* pSrcFont, FILE* pTmpFile,
197 const char* pGlyphSetName, int nGlyphCount,
198 /*const*/ const sal_uInt16* pRequestedGlyphs, /*const*/ const unsigned char* pEncoding,
199 bool bAllowType42 )
200{
201 // match the font-subset to the printer capabilities
202 // TODO: allow CFF for capable printers
203 FontType nTargetMask = FontType::TYPE1_PFA | FontType::TYPE3_FONT;
204 if( bAllowType42 )
8
Assuming 'bAllowType42' is false
9
Taking false branch
205 nTargetMask |= FontType::TYPE42_FONT;
206
207 std::vector< EncEntry > aSorted( nGlyphCount, EncEntry() );
208 for( int i = 0; i < nGlyphCount; i++ )
10
'i' initialized to 0
11
Assuming 'i' is < 'nGlyphCount'
12
Loop condition is true. Entering loop body
209 {
210 aSorted[i].aEnc = pEncoding[i];
13
Assigned value is garbage or undefined
211 aSorted[i].aGID = pRequestedGlyphs[i];
212 }
213
214 std::stable_sort( aSorted.begin(), aSorted.end() );
215
216 std::vector< unsigned char > aEncoding( nGlyphCount );
217 std::vector< sal_GlyphId > aRequestedGlyphs( nGlyphCount );
218
219 for( int i = 0; i < nGlyphCount; i++ )
220 {
221 aEncoding[i] = aSorted[i].aEnc;
222 aRequestedGlyphs[i] = aSorted[i].aGID;
223 }
224
225 FontSubsetInfo aInfo;
226 aInfo.LoadFont( pSrcFont );
227
228 aInfo.CreateFontSubset( nTargetMask, pTmpFile, pGlyphSetName,
229 aRequestedGlyphs.data(), aEncoding.data(), nGlyphCount );
230}
231
232void
233GlyphSet::PSUploadFont (osl::File& rOutFile, PrinterGfx &rGfx, bool bAllowType42, std::vector< OString >& rSuppliedFonts )
234{
235 TrueTypeFont *pTTFont;
236 OString aTTFileName (rGfx.GetFontMgr().getFontFileSysPath(mnFontID));
237 int nFace = rGfx.GetFontMgr().getFontFaceNumber(mnFontID);
238 SFErrCodes nSuccess = OpenTTFontFile(aTTFileName.getStr(), nFace, &pTTFont);
239 if (nSuccess != SFErrCodes::Ok)
1
Assuming 'nSuccess' is equal to Ok
2
Taking false branch
240 return;
241
242 utl::TempFile aTmpFile;
243 aTmpFile.EnableKillingFile();
244 FILE* pTmpFile = fopen(OUStringToOString(aTmpFile.GetFileName(), osl_getThreadTextEncoding()).getStr(), "w+b");
245 if (pTmpFile == nullptr)
3
Assuming the condition is false
4
Taking false branch
246 return;
247
248 // encoding vector maps character encoding to the ordinal number
249 // of the glyph in the output file
250 unsigned char pEncoding[256];
251 sal_uInt16 pTTGlyphMapping[256];
252
253 // loop through all the font glyph subsets
254 sal_Int32 nGlyphSetID = 1;
255 for (auto const& glyph : maGlyphList)
256 {
257 if (glyph.empty())
5
Assuming the condition is false
6
Taking false branch
258 {
259 ++nGlyphSetID;
260 continue;
261 }
262
263 // loop through all the glyphs in the subset
264 sal_Int32 n = 0;
265 for (auto const& elem : glyph)
266 {
267 pTTGlyphMapping [n] = elem.first;
268 pEncoding [n] = elem.second;
269 n++;
270 }
271
272 // create the current subset
273 OString aGlyphSetName = GetGlyphSetName(nGlyphSetID);
274 fprintf( pTmpFile, "%%%%BeginResource: font %s\n", aGlyphSetName.getStr() );
275 CreatePSUploadableFont( pTTFont, pTmpFile, aGlyphSetName.getStr(), glyph.size(),
7
Calling 'CreatePSUploadableFont'
276 pTTGlyphMapping, pEncoding, bAllowType42 );
277 fprintf( pTmpFile, "%%%%EndResource\n" );
278 rSuppliedFonts.push_back( aGlyphSetName );
279 ++nGlyphSetID;
280 }
281
282 // copy the file into the page header
283 rewind(pTmpFile);
284 fflush(pTmpFile);
285
286 unsigned char pBuffer[0x2000];
287 sal_uInt64 nIn;
288 sal_uInt64 nOut;
289 do
290 {
291 nIn = fread(pBuffer, 1, sizeof(pBuffer), pTmpFile);
292 rOutFile.write (pBuffer, nIn, nOut);
293 }
294 while ((nIn == nOut) && !feof(pTmpFile));
295
296 // cleanup
297 CloseTTFont (pTTFont);
298 fclose (pTmpFile);
299}
300
301/* vim:set shiftwidth=4 softtabstop=4 expandtab: */