1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
|
/**
* \file lzma/memlimit.h
* \brief Memory usage limitter
*
* \author Copyright (C) 1999-2006 Igor Pavlov
* \author Copyright (C) 2007 Lasse Collin
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
#ifndef LZMA_H_INTERNAL
# error Never include this file directly. Use <lzma.h> instead.
#endif
/**
* \brief Opaque data type used with the memory usage limitting functions
*/
typedef struct lzma_memlimit_s lzma_memlimit;
/**
* \brief Allocates and initializes a new lzma_memlimit structure
*
* It is easy to make liblzma to use huge amounts of memory. This can
* be a problem especially with the decoder, since it a file requiring
* huge amounts of memory to uncompress could allow even a denial of
* service attack if the memory usage wasn't limited.
*
* liblzma provides a set of functions to control memory usage. Pointers
* to these functions can be used in lzma_allocator structure, which makes
* it easy to limit memory usage with liblzma.
*
* The memory limitter functions are not tied to limitting memory usage
* with liblzma itself. You can use them with anything you like.
*
* In multi-threaded applications, only one thread at once may use the same
* lzma_memlimit structure. If there is a need, this limitation may
* be removed in future versions without breaking the libary API/ABI.
*
* \param limit Initial memory usage limit in bytes
*
* \return Pointer to allocated and initialized lzma_memlimit
* structure. On error, NULL is returned. The reason behind
* an error is either that malloc() failed or that the given
* limit was so small that it didn't allow allocating even
* the lzma_memlimit structure itself.
*
* \note Excluding lzma_memlimit_usage(), the functions whose name begin
* lzma_memlimit_ can be used even if lzma_init() hasn't been
* called.
*/
extern lzma_memlimit *lzma_memlimit_create(size_t limit);
/**
* \brief Sets a new memory usage limit
*
* \param mem Pointer to a lzma_memlimit structure returned
* earlier by lzma_memry_limit_create().
* \param limit New memory usage limit
*
* The new usage limit may be smaller than the amount of memory currently
* allocated via *mem: New allocations will fail until enough memory has
* been freed or a new limit is set, but the existing allocatations will
* stay untouched.
*/
extern void lzma_memlimit_set(lzma_memlimit *mem, size_t limit);
/**
* \brief Gets the current memory usage limit
*/
extern size_t lzma_memlimit_get(const lzma_memlimit *mem);
/**
* \brief Gets the amount of currently allocated memory
*
* \note This value includes the sizes of some helper structures,
* thus it will always be larger than the total number of
* bytes allocated via lzma_memlimit_alloc().
*/
extern size_t lzma_memlimit_used(const lzma_memlimit *mem);
/**
* \brief Gets the number of allocations owned by the memory limitter
*
* The count does not include the helper structures; if no memory has
* been allocated with lzma_memlimit_alloc() or all memory allocated
* has been freed or detached, this will return zero.
*/
extern size_t lzma_memlimit_count(const lzma_memlimit *mem);
/**
* \brief Allocates memory with malloc() if memory limit allows
*
* \param mem Pointer to a lzma_memlimit structure returned
* earlier by lzma_memry_limit_create().
* \param nmemb Number of elements to allocate. While liblzma always
* sets this to one, this function still takes the
* value of nmemb into account to keep the function
* usable with zlib and libbzip2.
* \param size Size of an element.
*
* \return Pointer to memory allocated with malloc(nmemb * size),
* except if nmemb * size == 0 which returns malloc(1).
* On error, NULL is returned.
*
* \note This function assumes that nmemb * size is at maximum of
* SIZE_MAX. If it isn't, an overflow will occur resulting
* invalid amount of memory being allocated.
*/
extern void *lzma_memlimit_alloc(
lzma_memlimit *mem, size_t nmemb, size_t size);
/**
* \brief Removes the pointer from memory limitting list
*
* \param mem Pointer to a lzma_memlimit structure returned
* earlier by lzma_memry_limit_create().
* \param ptr Pointer returned earlier by lzma_memlimit_alloc().
*
* This function removes ptr from the internal list and decreases the
* counter of used memory accordingly. The ptr itself isn't freed. This is
* useful when Extra Records allocated by liblzma using lzma_memlimit
* are needed by the application and must not be freed when the
* lzma_memlimit structure is destroyed.
*
* It is OK to call this function with ptr that hasn't been allocated with
* lzma_memlimit_alloc(). In that case, this has no effect other than wasting
* a few CPU cycles.
*/
extern void lzma_memlimit_detach(lzma_memlimit *mem, void *ptr);
/**
* \brief Frees memory and updates the memory limit list
*
* This is like lzma_memlimit_detach() but also frees the given pointer.
*/
extern void lzma_memlimit_free(lzma_memlimit *mem, void *ptr);
/**
* \brief Frees the memory allocated for and by the memory usage limitter
*
* \param mem Pointer to memory limitter
* \param free_allocated If this is non-zero, all the memory allocated
* by lzma_memlimit_alloc() using *mem is also
* freed if it hasn't already been freed with
* lzma_memlimit_free(). Usually this should be
* set to true.
*/
extern void lzma_memlimit_end(
lzma_memlimit *mem, lzma_bool free_allocated);
|