~ubuntu-branches/ubuntu/vivid/ghostscript/vivid-security

« back to all changes in this revision

Viewing changes to base/gp_ntfs.c

  • Committer: Package Import Robot
  • Author(s): Till Kamppeter
  • Date: 2013-08-09 20:01:36 UTC
  • mfrom: (1.1.37)
  • Revision ID: package-import@ubuntu.com-20130809200136-amb6zrr7hnjb5jq9
Tags: 9.08~rc1~dfsg-0ubuntu1
* New upstream release
   - Ghostscript 9.08rc1.
   - We are using the system's liblcms2 and libopenjpeg now.
* debian/patches/020130401-852e545-pxl-xl-driver-produced-drawing-commands-without-setting-color-space.patch:
  Removed patch backported from upstream.
* debian/patches/ojdk-8007925+8007926.patch,
  debian/patches/ojdk-8007927.patch,
  debian/patches/ojdk-8007929.patch,
  debian/patches/ojdk-8009654.patch: Removed patches on build in liblcms2, we
  use the system's liblcms2 now.
* debian/patches/2001_docdir_fix_for_debian.patch: Manually updated to new
  upstream source code.
* debian/patches/2003_support_multiarch.patch: Refreshed with quilt.
* debian/control: Added build dependencies on liblcms2-dev and
  libopenjpeg-dev.
* debian/rules: Check for removed lcms2/ and openjpeg/ subdirectories in
  the repackaging check again, also set build options for shared liblcms2
  and libopenjpeg libraries.
* debian/rules: Makefile.in and configure.ac are in the root directory of
  the source now and do not need to get linked from base/. Also there is no
  gstoraster and gstopxl CUPS filter in the package any more and no
  "install-cups" make target any more.
* debian/control, debian/rules, debian/ghostscript-cups.install,
  debian/ghostscript-cups.ppd-updater: Removed the ghostscript-cups binary
  package. The files are now provided by cups-filters.
* debian/symbols.common: Updated for new upstream source. Applied patch
  which dpkg-gensymbols generated for debian/libgs9.symbols to this file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
83
83
 
84
84
/* ------ File enumeration ------ */
85
85
 
86
 
struct file_enum_s {
87
 
#ifdef WINDOWS_NO_UNICODE
 
86
struct directory_enum_s {
 
87
#ifdef GS_NO_UTF8
88
88
    WIN32_FIND_DATA find_data;
89
89
#else
90
90
    WIN32_FIND_DATAW find_data;
97
97
    /* :, / or \ */
98
98
    int first_time;
99
99
    gs_memory_t *memory;
100
 
};
101
 
gs_private_st_ptrs1(st_file_enum, struct file_enum_s, "file_enum",
102
 
                    file_enum_enum_ptrs, file_enum_reloc_ptrs, pattern);
 
100
    struct directory_enum_s *previous;
 
101
};
 
102
gs_private_st_ptrs2(st_directory_enum, struct directory_enum_s, "directory_enum",
 
103
                    directory_enum_enum_ptrs, directory_enum_reloc_ptrs, pattern, previous);
 
104
 
 
105
typedef struct directory_enum_s directory_enum;
 
106
 
 
107
struct file_enum_s {
 
108
    struct directory_enum_s *current;
 
109
};
 
110
gs_private_st_ptrs1(st_file_enum, struct file_enum_s, "directory_enum",
 
111
                    file_enum_enum_ptrs, file_enum_reloc_ptrs, current);
 
112
 
 
113
static int enumerate_directory_init(gs_memory_t *mem, directory_enum *pden, const char *directory, int dir_size, char *filename, const char *pattern, int pat_size)
 
114
{
 
115
    int length = dir_size + pat_size;
 
116
 
 
117
    if (filename)
 
118
        length += strlen(filename);
 
119
 
 
120
    length = length * 2 + 3;
 
121
 
 
122
    /* pattern could be allocated as a string, */
 
123
    /* but it's simpler for GC and freeing to allocate it as bytes. */
 
124
    pden->pattern = (char *)gs_alloc_bytes(mem, length,
 
125
                                     "gp_enumerate_files(pattern)");
 
126
    if (pden->pattern == 0)
 
127
        return -1;
 
128
 
 
129
    memcpy(pden->pattern, directory, dir_size);
 
130
    if (directory[dir_size - 1] != '/') {
 
131
        pden->pattern[dir_size++] = '/';
 
132
    }
 
133
    if (filename) {
 
134
        memcpy(&pden->pattern[dir_size], filename, strlen(filename));
 
135
        dir_size += strlen(filename);
 
136
        pden->pattern[dir_size++] = '/';
 
137
    }
 
138
 
 
139
    memcpy(&(pden->pattern[dir_size]), pattern, pat_size);
 
140
    pden->pattern[dir_size + pat_size] = 0;
 
141
 
 
142
    pden->head_size = dir_size;
 
143
    pden->patlen = dir_size + pat_size;
 
144
    pden->pat_size = length;
 
145
    pden->memory = mem;
 
146
    pden->first_time = 1;
 
147
    memset(&pden->find_data, 0, sizeof(pden->find_data));
 
148
    pden->find_handle = INVALID_HANDLE_VALUE;
 
149
    pden->previous = 0L;
 
150
    return 0;
 
151
}
103
152
 
104
153
/* Initialize an enumeration.  Note that * and ? in a directory */
105
154
/* don't work with the OS call currently used. The '\' escape   */
107
156
file_enum *
108
157
gp_enumerate_files_init(const char *pat, uint patlen, gs_memory_t * mem)
109
158
{
110
 
    file_enum *pfen = gs_alloc_struct(mem, file_enum, &st_file_enum, "gp_enumerate_files");
 
159
    directory_enum *pden;
 
160
    file_enum *pfen;
111
161
    int pat_size = 2 * patlen + 1;
112
162
    char *pattern;
113
163
    int hsize = 0;
114
164
    int i, j;
115
165
 
116
 
    if (pfen == 0)
117
 
        return 0;
118
 
    /* pattern could be allocated as a string, */
119
 
    /* but it's simpler for GC and freeing to allocate it as bytes. */
120
 
    pattern = (char *)gs_alloc_bytes(mem, pat_size,
121
 
                                     "gp_enumerate_files(pattern)");
122
 
    if (pattern == 0)
123
 
        return 0;
124
 
    /* translate the template into a pattern discarding the escape  */
125
 
    /* char '\' (not needed by the OS Find...File logic). Note that */
126
 
    /* a final '\' in the string is also discarded.                 */
127
 
    for (i = 0, j=0; i < patlen; i++) {
128
 
        if (pat[i] == '\\') {
129
 
            i++;
130
 
            if (i == patlen)
131
 
                break;          /* '\' at end ignored */
132
 
        }
133
 
        pattern[j++]=pat[i];
 
166
    pden = gs_alloc_struct(mem, directory_enum, &st_directory_enum, "gp_enumerate_files");
 
167
    if (pden == 0)
 
168
        return 0;
 
169
    pfen = gs_alloc_struct(mem, file_enum, &st_file_enum, "gp_enumerate_files");
 
170
    if (pfen == 0) {
 
171
        gs_free_object(mem, pden, "free directory enumerator on error");
 
172
        return 0;
134
173
    }
 
174
    pfen->current = pden;
 
175
 
135
176
    /* Scan for last path separator to determine 'head_size' (directory part) */
136
 
    for (i = 0; i < j; i++) {
137
 
        if(pattern[i] == '/' || pattern[i] == '\\' || pattern[i] == ':')
138
 
        hsize = i+1;
139
 
    }
140
 
    pattern[j] = 0;
141
 
    pfen->pattern = pattern;
142
 
    pfen->patlen = j;
143
 
    pfen->pat_size = pat_size;
144
 
    pfen->head_size = hsize;
145
 
    pfen->memory = mem;
146
 
    pfen->first_time = 1;
147
 
    memset(&pfen->find_data, 0, sizeof(pfen->find_data));
148
 
    pfen->find_handle = INVALID_HANDLE_VALUE;
 
177
    for (i = 0; i < patlen; i++) {
 
178
        if(pat[i] == '/' || pat[i] == '\\' || pat[i] == ':')
 
179
        hsize = i + 1;
 
180
    }
 
181
 
 
182
    if (enumerate_directory_init(mem, pden, pat, hsize, NULL, &pat[hsize], patlen - hsize) < 0)
 
183
    {
 
184
        gs_free_object(mem, pden, "free directory enumerator on error");
 
185
        gs_free_object(mem, pfen, "free file enumerator on error");
 
186
        return 0;
 
187
    }
 
188
 
149
189
    return pfen;
150
190
}
151
191
 
153
193
uint
154
194
gp_enumerate_files_next(file_enum * pfen, char *ptr, uint maxlen)
155
195
{
 
196
    directory_enum *new_denum = NULL, *pden = pfen->current;
156
197
    int code = 0;
157
198
    uint len;
158
 
#ifdef WINDOWS_NO_UNICODE
 
199
#ifdef GS_NO_UTF8
159
200
    char *outfname;
160
201
#else
161
 
    char outfname[(sizeof(pfen->find_data.cFileName)*3+1)/2];
 
202
    char outfname[(sizeof(pden->find_data.cFileName)*3+1)/2];
162
203
#endif
163
204
    for(;;) {
164
 
        if (pfen->first_time) {
165
 
#ifdef WINDOWS_NO_UNICODE
166
 
            pfen->find_handle = FindFirstFile(pfen->pattern, &(pfen->find_data));
 
205
        if (pden->first_time) {
 
206
#ifdef GS_NO_UTF8
 
207
            pden->find_handle = FindFirstFile(pden->pattern, &(pden->find_data));
167
208
#else
168
209
            wchar_t *pat;
169
 
            pat = malloc(utf8_to_wchar(NULL, pfen->pattern)*sizeof(wchar_t));
 
210
            pat = malloc(utf8_to_wchar(NULL, pden->pattern)*sizeof(wchar_t));
170
211
            if (pat == NULL) {
171
212
                code = -1;
172
213
                break;
173
214
            }
174
 
            utf8_to_wchar(pat, pfen->pattern);
175
 
            pfen->find_handle = FindFirstFileW(pat, &(pfen->find_data));
 
215
            utf8_to_wchar(pat, pden->pattern);
 
216
#ifdef METRO
 
217
            pden->find_handle = FindFirstFileExW(pat, FindExInfoStandard, &(pden->find_data), FindExSearchNameMatch, NULL, 0);
 
218
#else
 
219
            pden->find_handle = FindFirstFileW(pat, &(pden->find_data));
 
220
#endif
176
221
            free(pat);
177
222
#endif
178
 
            if (pfen->find_handle == INVALID_HANDLE_VALUE) {
179
 
                code = -1;
180
 
                break;
 
223
            if (pden->find_handle == INVALID_HANDLE_VALUE) {
 
224
                if (pden->previous) {
 
225
                    FindClose(pden->find_handle);
 
226
                    gs_free_object(pden->memory, pden->pattern,
 
227
                       "gp_enumerate_files_close(pattern)");
 
228
                    new_denum = pden->previous;
 
229
                    gs_free_object(pden->memory, pden, "gp_enumerate_files_close");
 
230
                    pden = new_denum;
 
231
                    pfen->current = pden;
 
232
                    continue;
 
233
                } else {
 
234
                    code = -1;
 
235
                    break;
 
236
                }
181
237
            }
182
 
            pfen->first_time = 0;
 
238
            pden->first_time = 0;
183
239
        } else {
184
 
#ifdef WINDOWS_NO_UNICODE
185
 
            if (!FindNextFile(pfen->find_handle, &(pfen->find_data))) {
 
240
#ifdef GS_NO_UTF8
 
241
            if (!FindNextFile(pden->find_handle, &(pden->find_data))) {
186
242
#else
187
 
            if (!FindNextFileW(pfen->find_handle, &(pfen->find_data))) {
 
243
            if (!FindNextFileW(pden->find_handle, &(pden->find_data))) {
188
244
#endif
189
 
                code = -1;
190
 
                break;
 
245
                if (pden->previous) {
 
246
                    FindClose(pden->find_handle);
 
247
                    gs_free_object(pden->memory, pden->pattern,
 
248
                       "gp_enumerate_files_close(pattern)");
 
249
                    new_denum = pden->previous;
 
250
                    gs_free_object(pden->memory, pden, "gp_enumerate_files_close");
 
251
                    pden = new_denum;
 
252
                    pfen->current = pden;
 
253
                    continue;
 
254
                } else {
 
255
                    code = -1;
 
256
                    break;
 
257
                }
191
258
            }
192
259
        }
193
 
#ifdef WINDOWS_NO_UNICODE
194
 
        if ( strcmp(".",  pfen->find_data.cFileName)
195
 
          && strcmp("..", pfen->find_data.cFileName)
196
 
          && (pfen->find_data.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY))
197
 
            break;
 
260
#ifdef GS_NO_UTF8
 
261
        if ( strcmp(".",  pden->find_data.cFileName)
 
262
            && strcmp("..", pden->find_data.cFileName)) {
 
263
                if (pden->find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){
 
264
                    new_denum = gs_alloc_struct(pden->memory, directory_enum, &st_directory_enum, "gp_enumerate_files");
 
265
                    if (new_denum != 0) {
 
266
                        if (enumerate_directory_init(pden->memory, new_denum, pden->pattern, pden->head_size,
 
267
                            pden->find_data.cFileName, &pden->pattern[pden->head_size], pden->pat_size - pden->head_size) < 0)
 
268
                        {
 
269
                            gs_free_object(pden->memory, new_denum, "free directory enumerator on error");
 
270
                        }
 
271
                        new_denum->previous = pden;
 
272
                        pden = new_denum;
 
273
                        pfen->current = pden;
 
274
                    }
 
275
                }
 
276
                else
 
277
                    break;
 
278
        }
198
279
#else
199
 
        if ( wcscmp(L".",  pfen->find_data.cFileName)
200
 
          && wcscmp(L"..", pfen->find_data.cFileName)
201
 
          && (pfen->find_data.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY))
202
 
            break;
 
280
        if ( wcscmp(L".",  pden->find_data.cFileName)
 
281
            && wcscmp(L"..", pden->find_data.cFileName)) {
 
282
                if (pden->find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
 
283
                    new_denum = gs_alloc_struct(pden->memory, directory_enum, &st_directory_enum, "gp_enumerate_files");
 
284
                    if (new_denum != 0) {
 
285
                        char *fname;
 
286
                        fname = gs_alloc_bytes(pden->memory, wchar_to_utf8(NULL, pden->find_data.cFileName)*sizeof(wchar_t), "temporary wchar buffer");
 
287
                        if (fname == NULL) {
 
288
                            gs_free_object(pden->memory, new_denum, "free directory enumerator on error");
 
289
                        } else {
 
290
                            wchar_to_utf8(fname, pden->find_data.cFileName);
 
291
                            if (enumerate_directory_init(pden->memory, new_denum, pden->pattern, pden->head_size,
 
292
                                fname, &pden->pattern[pden->head_size], pden->pat_size - pden->head_size) < 0)
 
293
                            {
 
294
                                gs_free_object(pden->memory, new_denum, "free directory enumerator on error");
 
295
                            }
 
296
                            gs_free_object(pden->memory, fname, "free temporary wchar buffer");
 
297
                            new_denum->previous = pden;
 
298
                            pden = new_denum;
 
299
                            pfen->current = pden;
 
300
                        }
 
301
                    }
 
302
                }
 
303
                else
 
304
                    break;
 
305
        }
203
306
#endif
204
307
    }
205
308
 
207
310
        gp_enumerate_files_close(pfen);
208
311
        return ~(uint) 0;
209
312
    }
210
 
#ifdef WINDOWS_NO_UNICODE
211
 
    outfname = pfen->find_data.cFileName;
 
313
#ifdef GS_NO_UTF8
 
314
    outfname = pden->find_data.cFileName;
212
315
#else
213
 
    wchar_to_utf8(outfname, pfen->find_data.cFileName);
 
316
    wchar_to_utf8(outfname, pden->find_data.cFileName);
214
317
#endif
215
318
    len = strlen(outfname);
216
319
 
217
 
    if (pfen->head_size + len < maxlen) {
218
 
        memcpy(ptr, pfen->pattern, pfen->head_size);
219
 
        strcpy(ptr + pfen->head_size, outfname);
220
 
        return pfen->head_size + len;
 
320
    if (pden->head_size + len < maxlen) {
 
321
        memcpy(ptr, pden->pattern, pden->head_size);
 
322
        strcpy(ptr + pden->head_size, outfname);
 
323
        return pden->head_size + len;
221
324
    }
222
 
    if (pfen->head_size >= maxlen)
 
325
    if (pden->head_size >= maxlen)
223
326
        return 0;               /* no hope at all */
224
327
 
225
 
    memcpy(ptr, pfen->pattern, pfen->head_size);
226
 
    strncpy(ptr + pfen->head_size, outfname, maxlen - pfen->head_size - 1);
 
328
    memcpy(ptr, pden->pattern, pden->head_size);
 
329
    strncpy(ptr + pden->head_size, outfname, maxlen - pden->head_size - 1);
227
330
    return maxlen;
228
331
}
229
332
 
231
334
void
232
335
gp_enumerate_files_close(file_enum * pfen)
233
336
{
234
 
    gs_memory_t *mem = pfen->memory;
 
337
    directory_enum *ptenum, *pden = pfen->current;
 
338
    gs_memory_t *mem = pden->memory;
235
339
 
236
 
    if (pfen->find_handle != INVALID_HANDLE_VALUE)
237
 
        FindClose(pfen->find_handle);
238
 
    gs_free_object(mem, pfen->pattern,
 
340
    while (pden) {
 
341
        if (pden->find_handle != INVALID_HANDLE_VALUE)
 
342
            FindClose(pden->find_handle);
 
343
        gs_free_object(mem, pden->pattern,
239
344
                   "gp_enumerate_files_close(pattern)");
 
345
        ptenum = pden->previous;
 
346
        gs_free_object(mem, pden, "gp_enumerate_files_close");
 
347
        pden = ptenum;
 
348
    };
240
349
    gs_free_object(mem, pfen, "gp_enumerate_files_close");
241
350
}
242
351