~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/ipxe/src/tests/deflate_test.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU General Public License as
 
6
 * published by the Free Software Foundation; either version 2 of the
 
7
 * License, or any later version.
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful, but
 
10
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
12
 * General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software
 
16
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 
17
 * 02110-1301, USA.
 
18
 *
 
19
 * You can also choose to distribute this program under the terms of
 
20
 * the Unmodified Binary Distribution Licence (as given in the file
 
21
 * COPYING.UBDL), provided that you have satisfied its requirements.
 
22
 */
 
23
 
 
24
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
25
 
 
26
/** @file
 
27
 *
 
28
 * DEFLATE tests
 
29
 *
 
30
 */
 
31
 
 
32
/* Forcibly enable assertions */
 
33
#undef NDEBUG
 
34
 
 
35
#include <stdint.h>
 
36
#include <stdlib.h>
 
37
#include <string.h>
 
38
#include <ipxe/deflate.h>
 
39
#include <ipxe/test.h>
 
40
 
 
41
/** A DEFLATE test */
 
42
struct deflate_test {
 
43
        /** Compression format */
 
44
        enum deflate_format format;
 
45
        /** Compressed data */
 
46
        const void *compressed;
 
47
        /** Length of compressed data */
 
48
        size_t compressed_len;
 
49
        /** Expected uncompressed data */
 
50
        const void *expected;
 
51
        /** Length of expected uncompressed data */
 
52
        size_t expected_len;
 
53
};
 
54
 
 
55
/** A DEFLATE fragment list */
 
56
struct deflate_test_fragments {
 
57
        /** Fragment lengths */
 
58
        size_t len[8];
 
59
};
 
60
 
 
61
/** Define inline data */
 
62
#define DATA(...) { __VA_ARGS__ }
 
63
 
 
64
/** Define a DEFLATE test */
 
65
#define DEFLATE( name, FORMAT, COMPRESSED, EXPECTED )                   \
 
66
        static const uint8_t name ## _compressed[] = COMPRESSED;        \
 
67
        static const uint8_t name ## _expected[] = EXPECTED;            \
 
68
        static struct deflate_test name = {                             \
 
69
                .format = FORMAT,                                       \
 
70
                .compressed = name ## _compressed,                      \
 
71
                .compressed_len = sizeof ( name ## _compressed ),       \
 
72
                .expected = name ## _expected,                          \
 
73
                .expected_len = sizeof ( name ## _expected ),           \
 
74
        };
 
75
 
 
76
/* Empty file, no compression */
 
77
DEFLATE ( empty_literal, DEFLATE_RAW,
 
78
          DATA ( 0x01, 0x00, 0x00, 0xff, 0xff ), DATA() );
 
79
 
 
80
/* "iPXE" string, no compression */
 
81
DEFLATE ( literal, DEFLATE_RAW,
 
82
          DATA ( 0x01, 0x04, 0x00, 0xfb, 0xff, 0x69, 0x50, 0x58, 0x45 ),
 
83
          DATA ( 0x69, 0x50, 0x58, 0x45 ) );
 
84
 
 
85
/* "iPXE" string, no compression, split into two literals */
 
86
DEFLATE ( split_literal, DEFLATE_RAW,
 
87
          DATA ( 0x00, 0x02, 0x00, 0xfd, 0xff, 0x69, 0x50, 0x01, 0x02, 0x00,
 
88
                 0xfd, 0xff, 0x58, 0x45 ),
 
89
          DATA ( 0x69, 0x50, 0x58, 0x45 ) );
 
90
 
 
91
/* Empty file */
 
92
DEFLATE ( empty, DEFLATE_RAW, DATA ( 0x03, 0x00 ), DATA() );
 
93
 
 
94
/* "Hello world" */
 
95
DEFLATE ( hello_world, DEFLATE_RAW,
 
96
          DATA ( 0xf3, 0x48, 0xcd, 0xc9, 0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca,
 
97
                 0x49, 0x01, 0x00 ),
 
98
          DATA ( 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c,
 
99
                 0x64 ) );
 
100
 
 
101
/* "Hello hello world" */
 
102
DEFLATE ( hello_hello_world, DEFLATE_RAW,
 
103
          DATA ( 0xf3, 0x48, 0xcd, 0xc9, 0xc9, 0x57, 0xc8, 0x00, 0x93, 0xe5,
 
104
                 0xf9, 0x45, 0x39, 0x29, 0x00 ),
 
105
          DATA ( 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x68, 0x65, 0x6c, 0x6c,
 
106
                 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64 ) );
 
107
 
 
108
/* "This specification defines a lossless compressed data format" */
 
109
DEFLATE ( rfc_sentence, DEFLATE_RAW,
 
110
          DATA ( 0x0d, 0xc6, 0xdb, 0x09, 0x00, 0x21, 0x0c, 0x04, 0xc0, 0x56,
 
111
                 0xb6, 0x28, 0x1b, 0x08, 0x79, 0x70, 0x01, 0x35, 0xe2, 0xa6,
 
112
                 0x7f, 0xce, 0xf9, 0x9a, 0xf1, 0x25, 0xc1, 0xe3, 0x9a, 0x91,
 
113
                 0x2a, 0x9d, 0xb5, 0x61, 0x1e, 0xb9, 0x9d, 0x10, 0xcc, 0x22,
 
114
                 0xa7, 0x93, 0xd0, 0x5a, 0xe7, 0xbe, 0xb8, 0xc1, 0xa4, 0x05,
 
115
                 0x51, 0x77, 0x49, 0xff ),
 
116
          DATA ( 0x54, 0x68, 0x69, 0x73, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69,
 
117
                 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64,
 
118
                 0x65, 0x66, 0x69, 0x6e, 0x65, 0x73, 0x20, 0x61, 0x20, 0x6c,
 
119
                 0x6f, 0x73, 0x73, 0x6c, 0x65, 0x73, 0x73, 0x20, 0x63, 0x6f,
 
120
                 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x64,
 
121
                 0x61, 0x74, 0x61, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74 ) );
 
122
 
 
123
/* "ZLIB Compressed Data Format Specification" */
 
124
DEFLATE ( zlib, DEFLATE_ZLIB,
 
125
          DATA ( 0x78, 0x01, 0x8b, 0xf2, 0xf1, 0x74, 0x52, 0x70, 0xce, 0xcf,
 
126
                 0x2d, 0x28, 0x4a, 0x2d, 0x2e, 0x4e, 0x4d, 0x51, 0x70, 0x49,
 
127
                 0x2c, 0x49, 0x54, 0x70, 0xcb, 0x2f, 0xca, 0x4d, 0x2c, 0x51,
 
128
                 0x08, 0x2e, 0x48, 0x4d, 0xce, 0x4c, 0xcb, 0x4c, 0x4e, 0x2c,
 
129
                 0xc9, 0xcc, 0xcf, 0x03, 0x00, 0x2c, 0x0e, 0x0e, 0xeb ),
 
130
          DATA ( 0x5a, 0x4c, 0x49, 0x42, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x72,
 
131
                 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x44, 0x61, 0x74, 0x61,
 
132
                 0x20, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x53, 0x70,
 
133
                 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
 
134
                 0x6e ) );
 
135
 
 
136
/* "ZLIB Compressed Data Format Specification" fragment list */
 
137
static struct deflate_test_fragments zlib_fragments[] = {
 
138
        { { -1UL, } },
 
139
        { { 0, 1, 5, -1UL, } },
 
140
        { { 0, 0, 1, 0, 0, 1, -1UL } },
 
141
        { { 10, 8, 4, 7, 11, -1UL } },
 
142
        { { 45, -1UL } },
 
143
        { { 48, -1UL } },
 
144
};
 
145
 
 
146
/**
 
147
 * Report DEFLATE test result
 
148
 *
 
149
 * @v deflate           Decompressor
 
150
 * @v test              Deflate test
 
151
 * @v frags             Fragment list, or NULL
 
152
 * @v file              Test code file
 
153
 * @v line              Test code line
 
154
 */
 
155
static void deflate_okx ( struct deflate *deflate,
 
156
                          struct deflate_test *test,
 
157
                          struct deflate_test_fragments *frags,
 
158
                          const char *file, unsigned int line ) {
 
159
        uint8_t data[ test->expected_len ];
 
160
        struct deflate_chunk in;
 
161
        struct deflate_chunk out;
 
162
        size_t frag_len = -1UL;
 
163
        size_t offset = 0;
 
164
        size_t remaining = test->compressed_len;
 
165
        unsigned int i;
 
166
 
 
167
        /* Initialise decompressor */
 
168
        deflate_init ( deflate, test->format );
 
169
 
 
170
        /* Initialise output chunk */
 
171
        deflate_chunk_init ( &out, virt_to_user ( data ), 0, sizeof ( data ) );
 
172
 
 
173
        /* Process input (in fragments, if applicable) */
 
174
        for ( i = 0 ; i < ( sizeof ( frags->len ) /
 
175
                            sizeof ( frags->len[0] ) ) ; i++ ) {
 
176
 
 
177
                /* Initialise input chunk */
 
178
                if ( frags )
 
179
                        frag_len = frags->len[i];
 
180
                if ( frag_len > remaining )
 
181
                        frag_len = remaining;
 
182
                deflate_chunk_init ( &in, virt_to_user ( test->compressed ),
 
183
                                     offset, ( offset + frag_len ) );
 
184
 
 
185
                /* Decompress this fragment */
 
186
                okx ( deflate_inflate ( deflate, &in, &out ) == 0, file, line );
 
187
                okx ( in.len == ( offset + frag_len ), file, line );
 
188
                okx ( in.offset == in.len, file, line );
 
189
 
 
190
                /* Move to next fragment */
 
191
                offset = in.offset;
 
192
                remaining -= frag_len;
 
193
                if ( ! remaining )
 
194
                        break;
 
195
 
 
196
                /* Check that decompression has not terminated early */
 
197
                okx ( ! deflate_finished ( deflate ), file, line );
 
198
        }
 
199
 
 
200
        /* Check decompression has terminated as expected */
 
201
        okx ( deflate_finished ( deflate ), file, line );
 
202
        okx ( offset == test->compressed_len, file, line );
 
203
        okx ( out.offset == test->expected_len, file, line );
 
204
        okx ( memcmp ( data, test->expected, test->expected_len ) == 0,
 
205
             file, line );
 
206
}
 
207
#define deflate_ok( deflate, test, frags ) \
 
208
        deflate_okx ( deflate, test, frags, __FILE__, __LINE__ )
 
209
 
 
210
/**
 
211
 * Perform DEFLATE self-test
 
212
 *
 
213
 */
 
214
static void deflate_test_exec ( void ) {
 
215
        struct deflate *deflate;
 
216
        unsigned int i;
 
217
 
 
218
        /* Allocate shared structure */
 
219
        deflate = malloc ( sizeof ( *deflate ) );
 
220
        ok ( deflate != NULL );
 
221
 
 
222
        /* Perform self-tests */
 
223
        if ( deflate ) {
 
224
 
 
225
                /* Test as a single pass */
 
226
                deflate_ok ( deflate, &empty_literal, NULL );
 
227
                deflate_ok ( deflate, &literal, NULL );
 
228
                deflate_ok ( deflate, &split_literal, NULL );
 
229
                deflate_ok ( deflate, &empty, NULL );
 
230
                deflate_ok ( deflate, &hello_world, NULL );
 
231
                deflate_ok ( deflate, &hello_hello_world, NULL );
 
232
                deflate_ok ( deflate, &rfc_sentence, NULL );
 
233
                deflate_ok ( deflate, &zlib, NULL );
 
234
 
 
235
                /* Test fragmentation */
 
236
                for ( i = 0 ; i < ( sizeof ( zlib_fragments ) /
 
237
                                    sizeof ( zlib_fragments[0] ) ) ; i++ ) {
 
238
                        deflate_ok ( deflate, &zlib, &zlib_fragments[i] );
 
239
                }
 
240
        }
 
241
 
 
242
        /* Free shared structure */
 
243
        free ( deflate );
 
244
}
 
245
 
 
246
/** DEFLATE self-test */
 
247
struct self_test deflate_test __self_test = {
 
248
        .name = "deflate",
 
249
        .exec = deflate_test_exec,
 
250
};