iPXE
datauri.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2026 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 (at your option) 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
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25FILE_SECBOOT ( PERMITTED );
26
27#include <string.h>
28#include <strings.h>
29#include <errno.h>
30#include <ipxe/base64.h>
31#include <ipxe/blob.h>
32#include <ipxe/open.h>
33#include <ipxe/datauri.h>
34
35/** @file
36 *
37 * Data URIs
38 *
39 * The "data" URI scheme is defined in RFC 2397. In the interest of
40 * reducing code size, we support only a practical subset of the
41 * specification. Media types will be ignored (and must not contain a
42 * literal comma character). Base64 encoding is supported.
43 *
44 * URI encoding will already have been stripped by the URI parser.
45 * Special characters may therefore be used in the URI string
46 * (e.g. "hello%20world"). However, URI-encoded NUL bytes (%00) will
47 * not work as expected, since they will be interpreted as terminating
48 * the URI string. If NUL bytes are required, then Base64 encoding
49 * must be used instead.
50 */
51
52/**
53 * Parse data URI
54 *
55 * @v uri Data URI
56 * @v buf Buffer to fill in
57 * @ret len Length of data, or negative error
58 *
59 * The buffer length must be at least the size reported by
60 * datauri_max_len().
61 */
62int datauri_parse ( struct uri *uri, void *buf ) {
63 static const char b64marker[7] = ";base64";
64 const char *comma;
65 const char *encoded;
66 size_t prefix_len;
67 int len;
68 int rc;
69
70 /* Sanity check */
71 if ( ! uri->opaque ) {
72 DBGC ( uri, "DATA %p has no opaque part\n", uri );
73 return -EINVAL;
74 }
75
76 /* Locate encoded string */
77 comma = strchr ( uri->opaque, ',' );
78 if ( ! comma ) {
79 DBGC ( uri, "DATA %p has no comma separator\n", uri );
80 return -EINVAL;
81 }
82 prefix_len = ( comma - uri->opaque );
83 encoded = ( comma + 1 );
84 len = strlen ( encoded );
85
86 /* Decode string */
87 if ( ( prefix_len >= sizeof ( b64marker ) ) &&
88 ( strncasecmp ( ( comma - sizeof ( b64marker ) ), b64marker,
89 sizeof ( b64marker ) ) == 0 ) ) {
90
91 /* Decode Base64 string */
92 len = base64_decode ( encoded, buf, len );
93 if ( len < 0 ) {
94 rc = len;
95 DBGC ( uri, "DATA %p could not decode Base64: %s\n",
96 uri, strerror ( rc ) );
97 return rc;
98 }
99
100 } else {
101
102 /* Copy raw string */
103 strcpy ( buf, encoded );
104 }
105
106 DBGC ( uri, "DATA %p decoded \"%s\":\n", uri, uri->opaque );
107 DBGC_HDA ( uri, 0, buf, len );
108 return len;
109}
110
111/**
112 * Open data URI
113 *
114 * @v xfer Data transfer interface
115 * @v uri URI
116 * @ret rc Return status code
117 */
118static int datauri_open ( struct interface *xfer, struct uri *uri ) {
119 void *data;
120 int len;
121 int rc;
122
123 /* Allocate space for parsed data */
124 data = malloc ( datauri_max_len ( uri ) );
125 if ( ! data ) {
126 rc = -ENOMEM;
127 goto err_alloc;
128 }
129
130 /* Parse data */
131 len = datauri_parse ( uri, data );
132 if ( len < 0 ) {
133 rc = len;
134 goto err_parse;
135 }
136
137 /* Open downloadable blob */
138 if ( ( rc = blob_open ( xfer, data, len ) ) != 0 )
139 goto err_open;
140
141 err_open:
142 err_parse:
143 free ( data );
144 err_alloc:
145 return rc;
146}
147
148/** Data URI opener */
149struct uri_opener data_uri_opener __uri_opener = {
150 .scheme = "data",
151 .open = datauri_open,
152};
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
int base64_decode(const char *encoded, void *data, size_t len)
Base64-decode string.
Definition base64.c:92
Base64 encoding.
int blob_open(struct interface *xfer, const void *data, size_t len)
Open data blob.
Definition blob.c:110
Openable data blobs.
int datauri_parse(struct uri *uri, void *buf)
Parse data URI.
Definition datauri.c:62
static int datauri_open(struct interface *xfer, struct uri *uri)
Open data URI.
Definition datauri.c:118
Data URIs.
static size_t datauri_max_len(struct uri *uri)
Get maximum length of parsed data URI.
Definition datauri.h:23
ring len
Length.
Definition dwmac.h:226
uint8_t data[48]
Additional event data.
Definition ena.h:11
Error codes.
#define DBGC(...)
Definition compiler.h:530
#define DBGC_HDA(...)
Definition compiler.h:531
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:921
#define EINVAL
Invalid argument.
Definition errno.h:429
#define ENOMEM
Not enough space.
Definition errno.h:535
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:951
String functions.
String functions.
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:621
Data transfer interface opening.
#define __uri_opener
Register a URI opener.
Definition open.h:68
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
char * strchr(const char *src, int character)
Find character within a string.
Definition string.c:288
int strncasecmp(const char *first, const char *second, size_t max)
Compare case-insensitive strings.
Definition string.c:222
char * strcpy(char *dest, const char *src)
Copy string.
Definition string.c:378
size_t strlen(const char *src)
Get length of string.
Definition string.c:244
An object interface.
Definition interface.h:125
A URI opener.
Definition open.h:48
A Uniform Resource Identifier.
Definition uri.h:65
const char * opaque
Opaque part.
Definition uri.h:71