Coverage Report

Created: 2025-07-12 06:34

/src/h2o/lib/handler/file/templates.c.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 2014 DeNA Co., Ltd.
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a copy
5
 * of this software and associated documentation files (the "Software"), to
6
 * deal in the Software without restriction, including without limitation the
7
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8
 * sell copies of the Software, and to permit persons to whom the Software is
9
 * furnished to do so, subject to the following conditions:
10
 *
11
 * The above copyright notice and this permission notice shall be included in
12
 * all copies or substantial portions of the Software.
13
 *
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20
 * IN THE SOFTWARE.
21
 *
22
 * lib/file/templates.c.h is automatically generated from lib/file/_templates.h
23
 * with command:
24
 *   picotemplate.pl --conf=misc/picotemplate-conf.pl lib/file/_templates.c.h
25
 */
26
27
#include <limits.h>
28
29
static int cmpstrptr(const void *_x, const void *_y)
30
0
{
31
0
    const char *x = *(const char **)_x;
32
0
    const char *y = *(const char **)_y;
33
0
    return strcmp(x, y);
34
0
}
35
36
#if !defined(NAME_MAX) || defined(__linux__)
37
/* readdir(3) is known to be thread-safe on Linux and should be thread-safe on a platform that does not have a predefined value for
38
   NAME_MAX */
39
#define FOREACH_DIRENT(dp, dent)                                                                                                   \
40
0
    struct dirent *dent;                                                                                                           \
41
0
    while ((dent = readdir(dp)) != NULL)
42
#else
43
#define FOREACH_DIRENT(dp, dent)                                                                                                   \
44
    struct {                                                                                                                       \
45
        struct dirent d;                                                                                                           \
46
        char s[NAME_MAX + 1];                                                                                                      \
47
    } dent_;                                                                                                                       \
48
    struct dirent *dentp, *dent = &dent_.d;                                                                                        \
49
    int ret;                                                                                                                       \
50
    while ((ret = readdir_r(dp, dent, &dentp)) == 0 && dentp != NULL)
51
#endif /* FOREACH_DIRENT */
52
53
static h2o_buffer_t *build_dir_listing_html(h2o_mem_pool_t *pool, h2o_iovec_t path_normalized, DIR *dp)
54
0
{
55
0
    H2O_VECTOR(char *) files = {NULL};
56
57
0
    { /* build list of files */
58
0
        FOREACH_DIRENT(dp, dent)
59
0
        {
60
0
            if (strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0)
61
0
                continue;
62
0
            h2o_vector_reserve(pool, &files, files.size + 1);
63
0
            files.entries[files.size++] = h2o_strdup(pool, dent->d_name, SIZE_MAX).base;
64
0
        }
65
0
        if (files.size > 1)
66
0
            qsort(files.entries, files.size, sizeof(files.entries[0]), cmpstrptr);
67
0
    }
68
69
0
    h2o_buffer_t *_ = NULL;
70
0
    h2o_iovec_t path_normalized_escaped = h2o_htmlescape(pool, path_normalized.base, path_normalized.len);
71
72
0
    h2o_buffer_init(&_, &h2o_socket_buffer_prototype);
73
74
0
    {
75
0
        h2o_iovec_t _s = (h2o_iovec_init(H2O_STRLIT("<!DOCTYPE html>\n<TITLE>Index of ")));
76
0
        if (_s.len != 0 && _s.base[_s.len - 1] == '\n')
77
0
            --_s.len;
78
0
        if (h2o_buffer_try_reserve(&_, _s.len).base == NULL)
79
0
            goto NoMemory;
80
0
        memcpy(_->bytes + _->size, _s.base, _s.len);
81
0
        _->size += _s.len;
82
0
    }
83
0
    {
84
0
        h2o_iovec_t _s = (path_normalized_escaped);
85
0
        if (_s.len != 0 && _s.base[_s.len - 1] == '\n')
86
0
            --_s.len;
87
0
        if (h2o_buffer_try_reserve(&_, _s.len).base == NULL)
88
0
            goto NoMemory;
89
0
        memcpy(_->bytes + _->size, _s.base, _s.len);
90
0
        _->size += _s.len;
91
0
    }
92
0
    {
93
0
        h2o_iovec_t _s = (h2o_iovec_init(H2O_STRLIT("</TITLE>\n<H2>Index of ")));
94
0
        if (_s.len != 0 && _s.base[_s.len - 1] == '\n')
95
0
            --_s.len;
96
0
        if (h2o_buffer_try_reserve(&_, _s.len).base == NULL)
97
0
            goto NoMemory;
98
0
        memcpy(_->bytes + _->size, _s.base, _s.len);
99
0
        _->size += _s.len;
100
0
    }
101
0
    {
102
0
        h2o_iovec_t _s = (path_normalized_escaped);
103
0
        if (_s.len != 0 && _s.base[_s.len - 1] == '\n')
104
0
            --_s.len;
105
0
        if (h2o_buffer_try_reserve(&_, _s.len).base == NULL)
106
0
            goto NoMemory;
107
0
        memcpy(_->bytes + _->size, _s.base, _s.len);
108
0
        _->size += _s.len;
109
0
    }
110
0
    {
111
0
        h2o_iovec_t _s = (h2o_iovec_init(H2O_STRLIT("</H2>\n<UL>\n<LI><A HREF=\"..\">Parent Directory</A>\n")));
112
0
        if (_s.len != 0 && _s.base[_s.len - 1] == '\n')
113
0
            --_s.len;
114
0
        if (h2o_buffer_try_reserve(&_, _s.len).base == NULL)
115
0
            goto NoMemory;
116
0
        memcpy(_->bytes + _->size, _s.base, _s.len);
117
0
        _->size += _s.len;
118
0
    }
119
120
0
    size_t i;
121
0
    for (i = 0; i != files.size; ++i) {
122
0
        h2o_iovec_t link_escaped = h2o_uri_escape(pool, files.entries[i], strlen(files.entries[i]), NULL);
123
0
        link_escaped = h2o_htmlescape(pool, link_escaped.base, link_escaped.len);
124
0
        h2o_iovec_t label_escaped = h2o_htmlescape(pool, files.entries[i], strlen(files.entries[i]));
125
0
        {
126
0
            h2o_iovec_t _s = (h2o_iovec_init(H2O_STRLIT("<LI><A HREF=\"")));
127
0
            if (_s.len != 0 && _s.base[_s.len - 1] == '\n')
128
0
                --_s.len;
129
0
            if (h2o_buffer_try_reserve(&_, _s.len).base == NULL)
130
0
                goto NoMemory;
131
0
            memcpy(_->bytes + _->size, _s.base, _s.len);
132
0
            _->size += _s.len;
133
0
        }
134
0
        {
135
0
            h2o_iovec_t _s = (link_escaped);
136
0
            if (_s.len != 0 && _s.base[_s.len - 1] == '\n')
137
0
                --_s.len;
138
0
            if (h2o_buffer_try_reserve(&_, _s.len).base == NULL)
139
0
                goto NoMemory;
140
0
            memcpy(_->bytes + _->size, _s.base, _s.len);
141
0
            _->size += _s.len;
142
0
        }
143
0
        {
144
0
            h2o_iovec_t _s = (h2o_iovec_init(H2O_STRLIT("\">")));
145
0
            if (_s.len != 0 && _s.base[_s.len - 1] == '\n')
146
0
                --_s.len;
147
0
            if (h2o_buffer_try_reserve(&_, _s.len).base == NULL)
148
0
                goto NoMemory;
149
0
            memcpy(_->bytes + _->size, _s.base, _s.len);
150
0
            _->size += _s.len;
151
0
        }
152
0
        {
153
0
            h2o_iovec_t _s = (label_escaped);
154
0
            if (_s.len != 0 && _s.base[_s.len - 1] == '\n')
155
0
                --_s.len;
156
0
            if (h2o_buffer_try_reserve(&_, _s.len).base == NULL)
157
0
                goto NoMemory;
158
0
            memcpy(_->bytes + _->size, _s.base, _s.len);
159
0
            _->size += _s.len;
160
0
        }
161
0
        {
162
0
            h2o_iovec_t _s = (h2o_iovec_init(H2O_STRLIT("</A>\n")));
163
0
            if (_s.len != 0 && _s.base[_s.len - 1] == '\n')
164
0
                --_s.len;
165
0
            if (h2o_buffer_try_reserve(&_, _s.len).base == NULL)
166
0
                goto NoMemory;
167
0
            memcpy(_->bytes + _->size, _s.base, _s.len);
168
0
            _->size += _s.len;
169
0
        }
170
0
    }
171
0
    {
172
0
        h2o_iovec_t _s = (h2o_iovec_init(H2O_STRLIT("</UL>\n")));
173
0
        if (_s.len != 0 && _s.base[_s.len - 1] == '\n')
174
0
            --_s.len;
175
0
        if (h2o_buffer_try_reserve(&_, _s.len).base == NULL)
176
0
            goto NoMemory;
177
0
        memcpy(_->bytes + _->size, _s.base, _s.len);
178
0
        _->size += _s.len;
179
0
    }
180
181
0
    return _;
182
0
NoMemory:
183
0
    h2o_buffer_dispose(&_);
184
0
    return NULL;
185
0
}