xref: /freebsd/sys/contrib/dev/acpica/compiler/aslascii.c (revision c36e54bb328697af1e6113812caecbd3bac89fe0)
1 /******************************************************************************
2  *
3  * Module Name: aslascii - ASCII detection and support routines
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2015, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 #include <contrib/dev/acpica/compiler/aslcompiler.h>
45 #include <contrib/dev/acpica/include/acapps.h>
46 
47 #define _COMPONENT          ACPI_COMPILER
48         ACPI_MODULE_NAME    ("aslascii")
49 
50 
51 /* Local prototypes */
52 
53 static void
54 FlConsumeAnsiComment (
55     FILE                    *Handle,
56     ASL_FILE_STATUS         *Status);
57 
58 static void
59 FlConsumeNewComment (
60     FILE                    *Handle,
61     ASL_FILE_STATUS         *Status);
62 
63 
64 /*******************************************************************************
65  *
66  * FUNCTION:    FlCheckForAcpiTable
67  *
68  * PARAMETERS:  Handle              - Open input file
69  *
70  * RETURN:      Status
71  *
72  * DESCRIPTION: Determine if a file seems to be a binary ACPI table, via the
73  *              following checks on what would be the table header:
74  *              0) File must be at least as long as an ACPI_TABLE_HEADER
75  *              1) The header length field must match the file size
76  *              2) Signature, OemId, OemTableId, AslCompilerId must be ASCII
77  *
78  ******************************************************************************/
79 
80 ACPI_STATUS
81 FlCheckForAcpiTable (
82     FILE                    *Handle)
83 {
84     ACPI_TABLE_HEADER       Table;
85     UINT32                  FileSize;
86     size_t                  Actual;
87     UINT32                  i;
88 
89 
90     /* Read a potential table header */
91 
92     Actual = fread (&Table, 1, sizeof (ACPI_TABLE_HEADER), Handle);
93     fseek (Handle, 0, SEEK_SET);
94 
95     if (Actual < sizeof (ACPI_TABLE_HEADER))
96     {
97         return (AE_ERROR);
98     }
99 
100     /* Header length field must match the file size */
101 
102     FileSize = CmGetFileSize (Handle);
103     if (Table.Length != FileSize)
104     {
105         return (AE_ERROR);
106     }
107 
108     /*
109      * These fields must be ASCII:
110      * Signature, OemId, OemTableId, AslCompilerId.
111      * We allow a NULL terminator in OemId and OemTableId.
112      */
113     for (i = 0; i < ACPI_NAME_SIZE; i++)
114     {
115         if (!ACPI_IS_ASCII ((UINT8) Table.Signature[i]))
116         {
117             return (AE_ERROR);
118         }
119 
120         if (!ACPI_IS_ASCII ((UINT8) Table.AslCompilerId[i]))
121         {
122             return (AE_ERROR);
123         }
124     }
125 
126     for (i = 0; (i < ACPI_OEM_ID_SIZE) && (Table.OemId[i]); i++)
127     {
128         if (!ACPI_IS_ASCII ((UINT8) Table.OemId[i]))
129         {
130             return (AE_ERROR);
131         }
132     }
133 
134     for (i = 0; (i < ACPI_OEM_TABLE_ID_SIZE) && (Table.OemTableId[i]); i++)
135     {
136         if (!ACPI_IS_ASCII ((UINT8) Table.OemTableId[i]))
137         {
138             return (AE_ERROR);
139         }
140     }
141 
142     printf ("Binary file appears to be a valid ACPI table, disassembling\n");
143     return (AE_OK);
144 }
145 
146 
147 /*******************************************************************************
148  *
149  * FUNCTION:    FlCheckForAscii
150  *
151  * PARAMETERS:  Filename            - Full input filename
152  *              DisplayErrors       - TRUE if error messages desired
153  *
154  * RETURN:      Status
155  *
156  * DESCRIPTION: Verify that the input file is entirely ASCII. Ignores characters
157  *              within comments. Note: does not handle nested comments and does
158  *              not handle comment delimiters within string literals. However,
159  *              on the rare chance this happens and an invalid character is
160  *              missed, the parser will catch the error by failing in some
161  *              spectactular manner.
162  *
163  ******************************************************************************/
164 
165 ACPI_STATUS
166 FlCheckForAscii (
167     char                    *Filename,
168     BOOLEAN                 DisplayErrors)
169 {
170     UINT8                   Byte;
171     ACPI_SIZE               BadBytes = 0;
172     BOOLEAN                 OpeningComment = FALSE;
173     ASL_FILE_STATUS         Status;
174     FILE                    *Handle;
175 
176 
177     /* Open file in text mode so file offset is always accurate */
178 
179     Handle = fopen (Filename, "rb");
180 
181     Status.Line = 1;
182     Status.Offset = 0;
183 
184     /* Read the entire file */
185 
186     while (fread (&Byte, 1, 1, Handle) == 1)
187     {
188         /* Ignore comment fields (allow non-ascii within) */
189 
190         if (OpeningComment)
191         {
192             /* Check for second comment open delimiter */
193 
194             if (Byte == '*')
195             {
196                 FlConsumeAnsiComment (Handle, &Status);
197             }
198 
199             if (Byte == '/')
200             {
201                 FlConsumeNewComment (Handle, &Status);
202             }
203 
204             /* Reset */
205 
206             OpeningComment = FALSE;
207         }
208         else if (Byte == '/')
209         {
210             OpeningComment = TRUE;
211         }
212 
213         /* Check for an ASCII character */
214 
215         if (!ACPI_IS_ASCII (Byte))
216         {
217             if ((BadBytes < 10) && (DisplayErrors))
218             {
219                 AcpiOsPrintf (
220                     "Found non-ASCII character in source text: "
221                     "0x%2.2X in line %u, file offset 0x%2.2X\n",
222                     Byte, Status.Line, Status.Offset);
223             }
224             BadBytes++;
225         }
226 
227         /* Ensure character is either printable or a "space" char */
228 
229         else if (!isprint (Byte) && !isspace (Byte))
230         {
231             if ((BadBytes < 10) && (DisplayErrors))
232             {
233                 AcpiOsPrintf (
234                     "Found invalid character in source text: "
235                     "0x%2.2X in line %u, file offset 0x%2.2X\n",
236                     Byte, Status.Line, Status.Offset);
237             }
238             BadBytes++;
239         }
240 
241         /* Update line counter as necessary */
242 
243         if (Byte == 0x0A)
244         {
245             Status.Line++;
246         }
247 
248         Status.Offset++;
249     }
250 
251     fclose (Handle);
252 
253     /* Were there any non-ASCII characters in the file? */
254 
255     if (BadBytes)
256     {
257         if (DisplayErrors)
258         {
259             AcpiOsPrintf (
260                 "Total %u invalid characters found in input source text, "
261                 "could be a binary file\n", BadBytes);
262             AslError (ASL_ERROR, ASL_MSG_NON_ASCII, NULL, Filename);
263         }
264 
265         return (AE_BAD_CHARACTER);
266     }
267 
268     /* File is OK (100% ASCII) */
269 
270     return (AE_OK);
271 }
272 
273 
274 /*******************************************************************************
275  *
276  * FUNCTION:    FlConsumeAnsiComment
277  *
278  * PARAMETERS:  Handle              - Open input file
279  *              Status              - File current status struct
280  *
281  * RETURN:      Number of lines consumed
282  *
283  * DESCRIPTION: Step over a normal slash-star type comment
284  *
285  ******************************************************************************/
286 
287 static void
288 FlConsumeAnsiComment (
289     FILE                    *Handle,
290     ASL_FILE_STATUS         *Status)
291 {
292     UINT8                   Byte;
293     BOOLEAN                 ClosingComment = FALSE;
294 
295 
296     while (fread (&Byte, 1, 1, Handle) == 1)
297     {
298         /* Scan until comment close is found */
299 
300         if (ClosingComment)
301         {
302             if (Byte == '/')
303             {
304                 Status->Offset++;
305                 return;
306             }
307 
308             if (Byte != '*')
309             {
310                 /* Reset */
311 
312                 ClosingComment = FALSE;
313             }
314         }
315         else if (Byte == '*')
316         {
317             ClosingComment = TRUE;
318         }
319 
320         /* Maintain line count */
321 
322         if (Byte == 0x0A)
323         {
324             Status->Line++;
325         }
326 
327         Status->Offset++;
328     }
329 }
330 
331 
332 /*******************************************************************************
333  *
334  * FUNCTION:    FlConsumeNewComment
335  *
336  * PARAMETERS:  Handle              - Open input file
337  *              Status              - File current status struct
338  *
339  * RETURN:      Number of lines consumed
340  *
341  * DESCRIPTION: Step over a slash-slash type of comment
342  *
343  ******************************************************************************/
344 
345 static void
346 FlConsumeNewComment (
347     FILE                    *Handle,
348     ASL_FILE_STATUS         *Status)
349 {
350     UINT8                   Byte;
351 
352 
353     while (fread (&Byte, 1, 1, Handle) == 1)
354     {
355         Status->Offset++;
356 
357         /* Comment ends at newline */
358 
359         if (Byte == 0x0A)
360         {
361             Status->Line++;
362             return;
363         }
364     }
365 }
366