- fix: segfault on headerFree given malicious data.
[platform/upstream/rpm.git] / lib / header_internal.h
1 #ifndef H_HEADER_INTERNAL
2 #define H_HEADER_INTERNAL
3
4 /** \ingroup header
5  * \file lib/header_internal.h
6  */
7
8 #include <header.h>
9
10 #if !defined(__LCLINT__)
11 #include <netinet/in.h>
12 #endif  /* __LCLINT__ */
13
14 #define INDEX_MALLOC_SIZE       8
15
16 /*
17  * Teach header.c about legacy tags.
18  */
19 #define HEADER_OLDFILENAMES     1027
20 #define HEADER_BASENAMES        1117
21
22 /** \ingroup header
23  * Description of tag data.
24  */
25 typedef /*@abstract@*/ struct entryInfo * entryInfo;
26 struct entryInfo {
27     int_32 tag;                 /*!< Tag identifier. */
28     int_32 type;                /*!< Tag data type. */
29     int_32 offset;              /*!< Offset into data segment (ondisk only). */
30     int_32 count;               /*!< Number of tag elements. */
31 };
32
33 #define REGION_TAG_TYPE         RPM_BIN_TYPE
34 #define REGION_TAG_COUNT        sizeof(struct entryInfo)
35
36 #define ENTRY_IS_REGION(_e) \
37         (((_e)->info.tag >= HEADER_IMAGE) && ((_e)->info.tag < HEADER_REGIONS))
38 #define ENTRY_IN_REGION(_e)     ((_e)->info.offset < 0)
39
40 /** \ingroup header
41  * A single tag from a Header.
42  */
43 typedef /*@abstract@*/ struct indexEntry * indexEntry;
44 struct indexEntry {
45     struct entryInfo info;      /*!< Description of tag data. */
46 /*@owned@*/ void * data;        /*!< Location of tag data. */
47     int length;                 /*!< No. bytes of data. */
48     int rdlen;                  /*!< No. bytes of data in region. */
49 };
50
51 /** \ingroup header
52  * The Header data structure.
53  */
54 struct headerToken {
55 /*@unused@*/ struct HV_s hv;    /*!< Header public methods. */
56     void * blob;                /*!< Header region blob. */
57 /*@owned@*/ indexEntry index;   /*!< Array of tags. */
58     int indexUsed;              /*!< Current size of tag array. */
59     int indexAlloced;           /*!< Allocated size of tag array. */
60     int flags;
61 #define HEADERFLAG_SORTED       (1 << 0) /*!< Are header entries sorted? */
62 #define HEADERFLAG_ALLOCATED    (1 << 1) /*!< Is 1st header region allocated? */
63 #define HEADERFLAG_LEGACY       (1 << 2) /*!< Header came from legacy source? */
64 /*@refs@*/ int nrefs;   /*!< Reference count. */
65 };
66
67 /** \ingroup header
68  */
69 typedef /*@abstract@*/ struct sprintfTag * sprintfTag;
70 struct sprintfTag {
71 /*@null@*/ headerTagTagFunction ext;   /*!< if NULL tag element is invalid */
72     int extNum;
73     int_32 tag;
74     int justOne;
75     int arrayCount;
76 /*@kept@*/ char * format;
77 /*@kept@*/ /*@null@*/ char * type;
78     int pad;
79 };
80
81 /** \ingroup header
82  */
83 typedef /*@abstract@*/ struct extensionCache * extensionCache;
84 struct extensionCache {
85     int_32 type;
86     int_32 count;
87     int avail;
88     int freeit;
89 /*@owned@*/ const void * data;
90 };
91
92 /** \ingroup header
93  */
94 /*@-fielduse@*/
95 typedef /*@abstract@*/ struct sprintfToken * sprintfToken;
96 struct sprintfToken {
97     enum {
98         PTOK_NONE = 0,
99         PTOK_TAG,
100         PTOK_ARRAY,
101         PTOK_STRING,
102         PTOK_COND
103     } type;
104     union {
105         struct {
106         /*@only@*/ sprintfToken format;
107             int numTokens;
108         } array;
109         struct sprintfTag tag;
110         struct {
111         /*@dependent@*/ char * string;
112             int len;
113         } string;
114         struct {
115         /*@only@*/ /*@null@*/ sprintfToken ifFormat;
116             int numIfTokens;
117         /*@only@*/ /*@null@*/ sprintfToken elseFormat;
118             int numElseTokens;
119             struct sprintfTag tag;
120         } cond;
121     } u;
122 };
123 /*@=fielduse@*/
124
125 #ifdef __cplusplus
126 extern "C" {
127 #endif
128
129 /** \ingroup header
130  * Return array of locales found in header.
131  * The array is terminated with a NULL sentinel.
132  * @param h             header
133  * @return              array of locales (or NULL on error)
134  */
135 /*@unused@*/
136 /*@only@*/ /*@null@*/ char ** headerGetLangs(Header h)
137         /*@*/;
138
139 /** \ingroup header
140  * Retrieve tag value with type match.
141  * If *type is RPM_NULL_TYPE any type will match, otherwise only *type will
142  * match.
143  *
144  * @param h             header
145  * @param tag           tag
146  * @retval type         address of tag value data type (or NULL)
147  * @retval p            address of pointer to tag value(s) (or NULL)
148  * @retval c            address of number of values (or NULL)
149  * @return              1 on success, 0 on failure
150  */
151 /*@-exportlocal@*/
152 int headerGetRawEntry(Header h, int_32 tag,
153                         /*@null@*/ /*@out@*/ hTYP_t type,
154                         /*@null@*/ /*@out@*/ hPTR_t * p, 
155                         /*@null@*/ /*@out@*/ hCNT_t c)
156         /*@modifies *type, *p, *c @*/;
157 /*@=exportlocal@*/
158
159 /** \ingroup header
160  * Return header reference count.
161  * @param h             header
162  * @return              no. of references
163  */
164 /*@unused@*/ static inline int headerUsageCount(Header h) /*@*/ {
165     return h->nrefs;
166 }
167
168 /** \ingroup header
169  * Dump a header in human readable format (for debugging).
170  * @param h             header
171  * @param flags         0 or HEADER_DUMP_LINLINE
172  * @param tags          array of tag name/value pairs
173  */
174 /*@unused@*/
175 void headerDump(Header h, FILE *f, int flags,
176                 const struct headerTagTableEntry_s * tags)
177         /*@modifies f, fileSystem @*/;
178 #define HEADER_DUMP_INLINE   1
179
180 #ifdef __cplusplus
181 }   
182 #endif
183
184 #endif  /* H_HEADER_INTERNAL */