Coverage Report

Created: 2026-03-31 11:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/include/oox/ole/axbinaryreader.hxx
Line
Count
Source
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
#ifndef INCLUDED_OOX_OLE_AXBINARYREADER_HXX
21
#define INCLUDED_OOX_OLE_AXBINARYREADER_HXX
22
23
#include <cstddef>
24
#include <utility>
25
#include <vector>
26
27
#include <oox/helper/binaryinputstream.hxx>
28
#include <oox/helper/binarystreambase.hxx>
29
#include <oox/helper/refvector.hxx>
30
#include <rtl/ustring.hxx>
31
#include <sal/types.h>
32
33
namespace oox::ole { struct AxFontData; }
34
35
namespace oox::ole {
36
37
38
/** A wrapper for a binary input stream that supports aligned read operations.
39
40
    The implementation does not support seeking back the wrapped stream. All
41
    seeking operations (tell, seekTo, align) are performed relative to the
42
    position of the wrapped stream at construction time of this wrapper. It is
43
    possible to construct this wrapper with an unseekable input stream without
44
    losing any functionality.
45
 */
46
class AxAlignedInputStream final : public BinaryInputStream
47
{
48
public:
49
    explicit            AxAlignedInputStream( BinaryInputStream& rInStrm );
50
51
    /** Returns the size of the data this stream represents, if the wrapped
52
        stream supports the size() operation. */
53
    virtual sal_Int64   size() const override;
54
    /** Return the current relative stream position (relative to position of
55
        the wrapped stream at construction time). */
56
    virtual sal_Int64   tell() const override;
57
    /** Seeks the stream to the passed relative position, if it is behind the
58
        current position. */
59
    virtual void        seek( sal_Int64 nPos ) override;
60
    /** Closes the input stream but not the wrapped stream. */
61
    virtual void        close() override;
62
63
    /** Reads nBytes bytes to the passed sequence.
64
        @return  Number of bytes really read. */
65
    virtual sal_Int32   readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize = 1 ) override;
66
    /** Reads nBytes bytes to the (existing) buffer opMem.
67
        @return  Number of bytes really read. */
68
    virtual sal_Int32   readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize = 1 ) override;
69
    /** Seeks the stream forward by the passed number of bytes. */
70
    virtual void        skip( sal_Int32 nBytes, size_t nAtomSize = 1 ) override;
71
72
    /** Aligns the stream to a multiple of the passed size (relative to the
73
        position of the wrapped stream at construction time). */
74
    void                align( size_t nSize );
75
76
    /** Aligns the stream according to the passed type and reads a value. */
77
    template< typename Type >
78
    [[nodiscard]]
79
98
    Type                readAligned() { align( sizeof( Type ) ); return readValue< Type >(); }
unsigned int oox::ole::AxAlignedInputStream::readAligned<unsigned int>()
Line
Count
Source
79
52
    Type                readAligned() { align( sizeof( Type ) ); return readValue< Type >(); }
int oox::ole::AxAlignedInputStream::readAligned<int>()
Line
Count
Source
79
18
    Type                readAligned() { align( sizeof( Type ) ); return readValue< Type >(); }
unsigned char oox::ole::AxAlignedInputStream::readAligned<unsigned char>()
Line
Count
Source
79
28
    Type                readAligned() { align( sizeof( Type ) ); return readValue< Type >(); }
Unexecuted instantiation: unsigned short oox::ole::AxAlignedInputStream::readAligned<unsigned short>()
Unexecuted instantiation: short oox::ole::AxAlignedInputStream::readAligned<short>()
80
    /** Aligns the stream according to the passed type and skips the size of the type. */
81
    template< typename Type >
82
26
    void                skipAligned() { align( sizeof( Type ) ); skip( sizeof( Type ) ); }
Unexecuted instantiation: void oox::ole::AxAlignedInputStream::skipAligned<int>()
void oox::ole::AxAlignedInputStream::skipAligned<unsigned char>()
Line
Count
Source
82
18
    void                skipAligned() { align( sizeof( Type ) ); skip( sizeof( Type ) ); }
void oox::ole::AxAlignedInputStream::skipAligned<unsigned short>()
Line
Count
Source
82
8
    void                skipAligned() { align( sizeof( Type ) ); skip( sizeof( Type ) ); }
Unexecuted instantiation: void oox::ole::AxAlignedInputStream::skipAligned<unsigned int>()
Unexecuted instantiation: void oox::ole::AxAlignedInputStream::skipAligned<short>()
83
84
private:
85
    BinaryInputStream*  mpInStrm;           ///< The wrapped input stream.
86
    sal_Int64           mnStrmPos;          ///< Tracks relative position in the stream.
87
    sal_Int64           mnStrmSize;         ///< Size of the wrapped stream data.
88
};
89
90
91
/** A pair of integer values as a property. */
92
typedef ::std::pair< sal_Int32, sal_Int32 > AxPairData;
93
94
/** An array of string values as a property. */
95
typedef ::std::vector< OUString > AxArrayString;
96
97
98
/** Import helper to read simple and complex ActiveX form control properties
99
    from a binary input stream. */
100
class AxBinaryPropertyReader
101
{
102
public:
103
    explicit            AxBinaryPropertyReader( BinaryInputStream& rInStrm, bool b64BitPropFlags = false );
104
105
    /** Reads the next integer property value from the stream, if the
106
        respective flag in the property mask is set. */
107
    template< typename StreamType, typename DataType >
108
    void                readIntProperty( DataType& ornValue )
109
232
                            { if( startNextProperty() ) ornValue = maInStrm.readAligned< StreamType >(); }
void oox::ole::AxBinaryPropertyReader::readIntProperty<unsigned int, unsigned int>(unsigned int&)
Line
Count
Source
109
98
                            { if( startNextProperty() ) ornValue = maInStrm.readAligned< StreamType >(); }
void oox::ole::AxBinaryPropertyReader::readIntProperty<int, int>(int&)
Line
Count
Source
109
26
                            { if( startNextProperty() ) ornValue = maInStrm.readAligned< StreamType >(); }
void oox::ole::AxBinaryPropertyReader::readIntProperty<unsigned char, int>(int&)
Line
Count
Source
109
66
                            { if( startNextProperty() ) ornValue = maInStrm.readAligned< StreamType >(); }
void oox::ole::AxBinaryPropertyReader::readIntProperty<unsigned char, unsigned char>(unsigned char&)
Line
Count
Source
109
18
                            { if( startNextProperty() ) ornValue = maInStrm.readAligned< StreamType >(); }
void oox::ole::AxBinaryPropertyReader::readIntProperty<unsigned short, int>(int&)
Line
Count
Source
109
16
                            { if( startNextProperty() ) ornValue = maInStrm.readAligned< StreamType >(); }
void oox::ole::AxBinaryPropertyReader::readIntProperty<unsigned int, int>(int&)
Line
Count
Source
109
8
                            { if( startNextProperty() ) ornValue = maInStrm.readAligned< StreamType >(); }
Unexecuted instantiation: void oox::ole::AxBinaryPropertyReader::readIntProperty<short, int>(int&)
Unexecuted instantiation: void oox::ole::AxBinaryPropertyReader::readIntProperty<short, short>(short&)
Unexecuted instantiation: void oox::ole::AxBinaryPropertyReader::readIntProperty<unsigned short, unsigned short>(unsigned short&)
110
    /** Reads the next boolean property value from the stream, if the
111
        respective flag in the property mask is set. */
112
    void                readBoolProperty( bool& orbValue, bool bReverse = false );
113
    /** Reads the next pair property from the stream, if the respective flag in
114
        the property mask is set. */
115
    void                readPairProperty( AxPairData& orPairData );
116
    /** Reads the next string property from the stream, if the respective flag
117
        in the property mask is set. */
118
    void                readStringProperty( OUString& orValue );
119
    /** Reads ArrayString, an array of fmString ( compressed or uncompressed )
120
        is read from the stream and inserted into rStrings */
121
    void                readArrayStringProperty( std::vector< OUString >& rStrings );
122
    /** Reads the next GUID property from the stream, if the respective flag
123
        in the property mask is set. The GUID will be enclosed in braces. */
124
    void                readGuidProperty( OUString& orGuid );
125
    /** Reads the next font property from the stream, if the respective flag in
126
        the property mask is set. */
127
    void                readFontProperty( AxFontData& orFontData );
128
    /** Reads the next picture property from the stream, if the respective flag
129
        in the property mask is set. */
130
    void                readPictureProperty( StreamDataSequence& orPicData );
131
132
    /** Skips the next integer property value in the stream, if the respective
133
        flag in the property mask is set. */
134
    template< typename StreamType >
135
146
    void                skipIntProperty() { if( startNextProperty() ) maInStrm.skipAligned< StreamType >(); }
void oox::ole::AxBinaryPropertyReader::skipIntProperty<int>()
Line
Count
Source
135
18
    void                skipIntProperty() { if( startNextProperty() ) maInStrm.skipAligned< StreamType >(); }
void oox::ole::AxBinaryPropertyReader::skipIntProperty<unsigned char>()
Line
Count
Source
135
52
    void                skipIntProperty() { if( startNextProperty() ) maInStrm.skipAligned< StreamType >(); }
void oox::ole::AxBinaryPropertyReader::skipIntProperty<unsigned short>()
Line
Count
Source
135
52
    void                skipIntProperty() { if( startNextProperty() ) maInStrm.skipAligned< StreamType >(); }
void oox::ole::AxBinaryPropertyReader::skipIntProperty<unsigned int>()
Line
Count
Source
135
8
    void                skipIntProperty() { if( startNextProperty() ) maInStrm.skipAligned< StreamType >(); }
void oox::ole::AxBinaryPropertyReader::skipIntProperty<short>()
Line
Count
Source
135
16
    void                skipIntProperty() { if( startNextProperty() ) maInStrm.skipAligned< StreamType >(); }
136
    /** Skips the next boolean property value in the stream, if the respective
137
        flag in the property mask is set. */
138
8
    void                skipBoolProperty() { (void)startNextProperty(); }
139
    /** Skips the next string property in the stream, if the respective flag in
140
        the property mask is set. */
141
0
    void                skipStringProperty() { readStringProperty( maDummyString ); }
142
    /** Skips the next ArrayString property in the stream, if the respective flag in
143
        the property mask is set. */
144
0
    void                skipArrayStringProperty() { readArrayStringProperty( maDummyArrayString ); }
145
    /** Skips the next GUID property in the stream, if the respective flag in
146
        the property mask is set. */
147
0
    void                skipGuidProperty() { readGuidProperty( maDummyString ); }
148
    /** Skips the next picture property in the stream, if the respective flag
149
        in the property mask is set. */
150
18
    void                skipPictureProperty() { readPictureProperty( maDummyPicData ); }
151
    /** Has to be called for undefined properties. If the respective flag in
152
        the mask is set, the property import cannot be finished successfully. */
153
16
    void                skipUndefinedProperty() { ensureValid( !startNextProperty() ); }
154
155
    /** Final processing, reads contents of all complex properties. */
156
    bool                finalizeImport();
157
158
private:
159
    bool                ensureValid( bool bCondition = true );
160
    bool                startNextProperty();
161
162
private:
163
    /** Base class for complex properties such as string, point, size, GUID, picture. */
164
    struct ComplexProperty
165
    {
166
        virtual             ~ComplexProperty();
167
        virtual bool        readProperty( AxAlignedInputStream& rInStrm ) = 0;
168
    };
169
170
    /** Complex property for a 32-bit value pair, e.g. point or size. */
171
    struct PairProperty final : public ComplexProperty
172
    {
173
    private:
174
        AxPairData&         mrPairData;
175
    public:
176
        explicit            PairProperty( AxPairData& rPairData ) :
177
18
                                mrPairData( rPairData ) {}
178
        virtual bool        readProperty( AxAlignedInputStream& rInStrm ) override;
179
    };
180
181
    /** Complex property for a string value. */
182
    struct StringProperty final : public ComplexProperty
183
    {
184
    private:
185
        OUString&    mrValue;
186
        sal_uInt32          mnSize;
187
    public:
188
        explicit            StringProperty( OUString& rValue, sal_uInt32 nSize ) :
189
36
                                mrValue( rValue ), mnSize( nSize ) {}
190
        virtual bool        readProperty( AxAlignedInputStream& rInStrm ) override;
191
    };
192
193
    /** Complex property for an array of strings. */
194
    struct ArrayStringProperty final : public ComplexProperty
195
    {
196
    private:
197
        AxArrayString&      mrArray;
198
        sal_uInt32          mnSize;
199
    public:
200
        explicit            ArrayStringProperty( AxArrayString& rArray, sal_uInt32 nSize ) :
201
0
                                mrArray( rArray ), mnSize( nSize ) {}
202
        virtual bool        readProperty( AxAlignedInputStream& rInStrm ) override;
203
    };
204
205
    /** Complex property for a GUID value. */
206
    struct GuidProperty final : public ComplexProperty
207
    {
208
    private:
209
        OUString&    mrGuid;
210
211
    public:
212
        explicit            GuidProperty( OUString& rGuid ) :
213
0
                                mrGuid( rGuid ) {}
214
        virtual bool        readProperty( AxAlignedInputStream& rInStrm ) override;
215
    };
216
217
    /** Stream property for a font structure. */
218
    struct FontProperty final : public ComplexProperty
219
    {
220
    private:
221
        AxFontData&         mrFontData;
222
223
    public:
224
        explicit            FontProperty( AxFontData& rFontData ) :
225
0
                                mrFontData( rFontData ) {}
226
        virtual bool        readProperty( AxAlignedInputStream& rInStrm ) override;
227
    };
228
229
    /** Stream property for a picture or mouse icon. */
230
    struct PictureProperty final : public ComplexProperty
231
    {
232
    private:
233
        StreamDataSequence& mrPicData;
234
235
    public:
236
        explicit            PictureProperty( StreamDataSequence& rPicData ) :
237
0
                                mrPicData( rPicData ) {}
238
        virtual bool        readProperty( AxAlignedInputStream& rInStrm ) override;
239
    };
240
241
    typedef RefVector< ComplexProperty > ComplexPropVector;
242
243
private:
244
    AxAlignedInputStream maInStrm;          ///< The input stream to read from.
245
    ComplexPropVector   maLargeProps;       ///< Stores info for all used large properties.
246
    ComplexPropVector   maStreamProps;      ///< Stores info for all used stream data properties.
247
    StreamDataSequence  maDummyPicData;     ///< Dummy picture for unsupported properties.
248
    OUString            maDummyString;      ///< Dummy string for unsupported properties.
249
    AxArrayString       maDummyArrayString; ///< Dummy strings for unsupported ArrayString properties.
250
    sal_Int64           mnPropFlags;        ///< Flags specifying existing properties.
251
    sal_Int64           mnNextProp;         ///< Next property to read.
252
    sal_Int64           mnPropsEnd;         ///< End position of simple/large properties.
253
    bool                mbValid;            ///< True = stream still valid.
254
};
255
256
257
} // namespace oox::ole
258
259
#endif
260
261
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */