blob: e65c54361428c1305e70aa7496f4a05602b1d51e [file] [log] [blame]
Andrew Geissler82c905d2020-04-13 13:39:40 -05001From 8af168cefca01f8f2da336f1c82620c284dc74f2 Mon Sep 17 00:00:00 2001
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08002From: Chen Qi <Qi.Chen@windriver.com>
Brad Bishop19323692019-04-05 15:28:33 -04003Date: Mon, 25 Feb 2019 14:04:21 +0800
Andrew Geissler82c905d2020-04-13 13:39:40 -05004Subject: [PATCH] add fallback parse_printf_format implementation
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08005
6Upstream-Status: Inappropriate [musl specific]
7
8Signed-off-by: Emil Renner Berthing <systemd@esmil.dk>
9Signed-off-by: Khem Raj <raj.khem@gmail.com>
10Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
Brad Bishopa34c0302019-09-23 22:34:48 -040011[rebased for systemd 243]
12Signed-off-by: Scott Murray <scott.murray@konsulko.com>
Andrew Geissler82c905d2020-04-13 13:39:40 -050013
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080014---
15 meson.build | 1 +
16 src/basic/meson.build | 5 +
Andrew Geissler82c905d2020-04-13 13:39:40 -050017 src/basic/parse-printf-format.c | 273 ++++++++++++++++++++++++++++++++
18 src/basic/parse-printf-format.h | 57 +++++++
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080019 src/basic/stdio-util.h | 2 +-
20 src/journal/journal-send.c | 2 +-
21 6 files changed, 338 insertions(+), 2 deletions(-)
22 create mode 100644 src/basic/parse-printf-format.c
23 create mode 100644 src/basic/parse-printf-format.h
24
Andrew Geissler635e0e42020-08-21 15:58:33 -050025Index: systemd-stable/meson.build
26===================================================================
27--- systemd-stable.orig/meson.build
28+++ systemd-stable/meson.build
29@@ -638,6 +638,7 @@ endif
Brad Bishopa34c0302019-09-23 22:34:48 -040030 foreach header : ['crypt.h',
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080031 'linux/memfd.h',
32 'linux/vm_sockets.h',
33+ 'printf.h',
34 'sys/auxv.h',
35 'valgrind/memcheck.h',
36 'valgrind/valgrind.h',
Andrew Geissler635e0e42020-08-21 15:58:33 -050037Index: systemd-stable/src/basic/meson.build
38===================================================================
39--- systemd-stable.orig/src/basic/meson.build
40+++ systemd-stable/src/basic/meson.build
41@@ -317,6 +317,11 @@ foreach item : [['af', af_list_txt,
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080042 endforeach
43
Brad Bishop19323692019-04-05 15:28:33 -040044 basic_sources += generated_gperf_headers
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080045+
46+if conf.get('HAVE_PRINTF_H') != 1
47+ basic_sources += [files('parse-printf-format.c')]
48+endif
49+
50 basic_gcrypt_sources = files(
51 'gcrypt-util.c',
52 'gcrypt-util.h')
Andrew Geissler635e0e42020-08-21 15:58:33 -050053Index: systemd-stable/src/basic/parse-printf-format.c
54===================================================================
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080055--- /dev/null
Andrew Geissler635e0e42020-08-21 15:58:33 -050056+++ systemd-stable/src/basic/parse-printf-format.c
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080057@@ -0,0 +1,273 @@
58+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
59+
60+/***
61+ This file is part of systemd.
62+
63+ Copyright 2014 Emil Renner Berthing <systemd@esmil.dk>
64+
65+ With parts from the musl C library
66+ Copyright 2005-2014 Rich Felker, et al.
67+
68+ systemd is free software; you can redistribute it and/or modify it
69+ under the terms of the GNU Lesser General Public License as published by
70+ the Free Software Foundation; either version 2.1 of the License, or
71+ (at your option) any later version.
72+
73+ systemd is distributed in the hope that it will be useful, but
74+ WITHOUT ANY WARRANTY; without even the implied warranty of
75+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
76+ Lesser General Public License for more details.
77+
78+ You should have received a copy of the GNU Lesser General Public License
79+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
80+***/
81+
82+#include <stddef.h>
83+#include <string.h>
84+
85+#include "parse-printf-format.h"
86+
87+static const char *consume_nonarg(const char *fmt)
88+{
89+ do {
90+ if (*fmt == '\0')
91+ return fmt;
92+ } while (*fmt++ != '%');
93+ return fmt;
94+}
95+
96+static const char *consume_num(const char *fmt)
97+{
98+ for (;*fmt >= '0' && *fmt <= '9'; fmt++)
99+ /* do nothing */;
100+ return fmt;
101+}
102+
103+static const char *consume_argn(const char *fmt, size_t *arg)
104+{
105+ const char *p = fmt;
106+ size_t val = 0;
107+
108+ if (*p < '1' || *p > '9')
109+ return fmt;
110+ do {
111+ val = 10*val + (*p++ - '0');
112+ } while (*p >= '0' && *p <= '9');
113+
114+ if (*p != '$')
115+ return fmt;
116+ *arg = val;
117+ return p+1;
118+}
119+
120+static const char *consume_flags(const char *fmt)
121+{
122+ while (1) {
123+ switch (*fmt) {
124+ case '#':
125+ case '0':
126+ case '-':
127+ case ' ':
128+ case '+':
129+ case '\'':
130+ case 'I':
131+ fmt++;
132+ continue;
133+ }
134+ return fmt;
135+ }
136+}
137+
138+enum state {
139+ BARE,
140+ LPRE,
141+ LLPRE,
142+ HPRE,
143+ HHPRE,
144+ BIGLPRE,
145+ ZTPRE,
146+ JPRE,
147+ STOP
148+};
149+
150+enum type {
151+ NONE,
152+ PTR,
153+ INT,
154+ UINT,
155+ ULLONG,
156+ LONG,
157+ ULONG,
158+ SHORT,
159+ USHORT,
160+ CHAR,
161+ UCHAR,
162+ LLONG,
163+ SIZET,
164+ IMAX,
165+ UMAX,
166+ PDIFF,
167+ UIPTR,
168+ DBL,
169+ LDBL,
170+ MAXTYPE
171+};
172+
173+static const short pa_types[MAXTYPE] = {
174+ [NONE] = PA_INT,
175+ [PTR] = PA_POINTER,
176+ [INT] = PA_INT,
177+ [UINT] = PA_INT,
178+ [ULLONG] = PA_INT | PA_FLAG_LONG_LONG,
179+ [LONG] = PA_INT | PA_FLAG_LONG,
180+ [ULONG] = PA_INT | PA_FLAG_LONG,
181+ [SHORT] = PA_INT | PA_FLAG_SHORT,
182+ [USHORT] = PA_INT | PA_FLAG_SHORT,
183+ [CHAR] = PA_CHAR,
184+ [UCHAR] = PA_CHAR,
185+ [LLONG] = PA_INT | PA_FLAG_LONG_LONG,
186+ [SIZET] = PA_INT | PA_FLAG_LONG,
187+ [IMAX] = PA_INT | PA_FLAG_LONG_LONG,
188+ [UMAX] = PA_INT | PA_FLAG_LONG_LONG,
189+ [PDIFF] = PA_INT | PA_FLAG_LONG_LONG,
190+ [UIPTR] = PA_INT | PA_FLAG_LONG,
191+ [DBL] = PA_DOUBLE,
192+ [LDBL] = PA_DOUBLE | PA_FLAG_LONG_DOUBLE
193+};
194+
195+#define S(x) [(x)-'A']
196+#define E(x) (STOP + (x))
197+
198+static const unsigned char states[]['z'-'A'+1] = {
199+ { /* 0: bare types */
200+ S('d') = E(INT), S('i') = E(INT),
201+ S('o') = E(UINT),S('u') = E(UINT),S('x') = E(UINT), S('X') = E(UINT),
202+ S('e') = E(DBL), S('f') = E(DBL), S('g') = E(DBL), S('a') = E(DBL),
203+ S('E') = E(DBL), S('F') = E(DBL), S('G') = E(DBL), S('A') = E(DBL),
204+ S('c') = E(CHAR),S('C') = E(INT),
205+ S('s') = E(PTR), S('S') = E(PTR), S('p') = E(UIPTR),S('n') = E(PTR),
206+ S('m') = E(NONE),
207+ S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE,
208+ S('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE
209+ }, { /* 1: l-prefixed */
210+ S('d') = E(LONG), S('i') = E(LONG),
211+ S('o') = E(ULONG),S('u') = E(ULONG),S('x') = E(ULONG),S('X') = E(ULONG),
212+ S('e') = E(DBL), S('f') = E(DBL), S('g') = E(DBL), S('a') = E(DBL),
213+ S('E') = E(DBL), S('F') = E(DBL), S('G') = E(DBL), S('A') = E(DBL),
214+ S('c') = E(INT), S('s') = E(PTR), S('n') = E(PTR),
215+ S('l') = LLPRE
216+ }, { /* 2: ll-prefixed */
217+ S('d') = E(LLONG), S('i') = E(LLONG),
218+ S('o') = E(ULLONG),S('u') = E(ULLONG),
219+ S('x') = E(ULLONG),S('X') = E(ULLONG),
220+ S('n') = E(PTR)
221+ }, { /* 3: h-prefixed */
222+ S('d') = E(SHORT), S('i') = E(SHORT),
223+ S('o') = E(USHORT),S('u') = E(USHORT),
224+ S('x') = E(USHORT),S('X') = E(USHORT),
225+ S('n') = E(PTR),
226+ S('h') = HHPRE
227+ }, { /* 4: hh-prefixed */
228+ S('d') = E(CHAR), S('i') = E(CHAR),
229+ S('o') = E(UCHAR),S('u') = E(UCHAR),
230+ S('x') = E(UCHAR),S('X') = E(UCHAR),
231+ S('n') = E(PTR)
232+ }, { /* 5: L-prefixed */
233+ S('e') = E(LDBL),S('f') = E(LDBL),S('g') = E(LDBL), S('a') = E(LDBL),
234+ S('E') = E(LDBL),S('F') = E(LDBL),S('G') = E(LDBL), S('A') = E(LDBL),
235+ S('n') = E(PTR)
236+ }, { /* 6: z- or t-prefixed (assumed to be same size) */
237+ S('d') = E(PDIFF),S('i') = E(PDIFF),
238+ S('o') = E(SIZET),S('u') = E(SIZET),
239+ S('x') = E(SIZET),S('X') = E(SIZET),
240+ S('n') = E(PTR)
241+ }, { /* 7: j-prefixed */
242+ S('d') = E(IMAX), S('i') = E(IMAX),
243+ S('o') = E(UMAX), S('u') = E(UMAX),
244+ S('x') = E(UMAX), S('X') = E(UMAX),
245+ S('n') = E(PTR)
246+ }
247+};
248+
249+size_t parse_printf_format(const char *fmt, size_t n, int *types)
250+{
251+ size_t i = 0;
252+ size_t last = 0;
253+
254+ memset(types, 0, n);
255+
256+ while (1) {
257+ size_t arg;
258+ unsigned int state;
259+
260+ fmt = consume_nonarg(fmt);
261+ if (*fmt == '\0')
262+ break;
263+ if (*fmt == '%') {
264+ fmt++;
265+ continue;
266+ }
267+ arg = 0;
268+ fmt = consume_argn(fmt, &arg);
269+ /* flags */
270+ fmt = consume_flags(fmt);
271+ /* width */
272+ if (*fmt == '*') {
273+ size_t warg = 0;
274+ fmt = consume_argn(fmt+1, &warg);
275+ if (warg == 0)
276+ warg = ++i;
277+ if (warg > last)
278+ last = warg;
279+ if (warg <= n && types[warg-1] == NONE)
280+ types[warg-1] = INT;
281+ } else
282+ fmt = consume_num(fmt);
283+ /* precision */
284+ if (*fmt == '.') {
285+ fmt++;
286+ if (*fmt == '*') {
287+ size_t parg = 0;
288+ fmt = consume_argn(fmt+1, &parg);
289+ if (parg == 0)
290+ parg = ++i;
291+ if (parg > last)
292+ last = parg;
293+ if (parg <= n && types[parg-1] == NONE)
294+ types[parg-1] = INT;
295+ } else {
296+ if (*fmt == '-')
297+ fmt++;
298+ fmt = consume_num(fmt);
299+ }
300+ }
301+ /* length modifier and conversion specifier */
302+ state = BARE;
303+ do {
304+ unsigned char c = *fmt++;
305+
306+ if (c < 'A' || c > 'z')
307+ continue;
308+ state = states[state]S(c);
309+ if (state == 0)
310+ continue;
311+ } while (state < STOP);
312+
313+ if (state == E(NONE))
314+ continue;
315+
316+ if (arg == 0)
317+ arg = ++i;
318+ if (arg > last)
319+ last = arg;
320+ if (arg <= n)
321+ types[arg-1] = state - STOP;
322+ }
323+
324+ if (last > n)
325+ last = n;
326+ for (i = 0; i < last; i++)
327+ types[i] = pa_types[types[i]];
328+
329+ return last;
330+}
Andrew Geissler635e0e42020-08-21 15:58:33 -0500331Index: systemd-stable/src/basic/parse-printf-format.h
332===================================================================
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800333--- /dev/null
Andrew Geissler635e0e42020-08-21 15:58:33 -0500334+++ systemd-stable/src/basic/parse-printf-format.h
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800335@@ -0,0 +1,57 @@
336+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
337+
338+/***
339+ This file is part of systemd.
340+
341+ Copyright 2014 Emil Renner Berthing <systemd@esmil.dk>
342+
343+ With parts from the GNU C Library
344+ Copyright 1991-2014 Free Software Foundation, Inc.
345+
346+ systemd is free software; you can redistribute it and/or modify it
347+ under the terms of the GNU Lesser General Public License as published by
348+ the Free Software Foundation; either version 2.1 of the License, or
349+ (at your option) any later version.
350+
351+ systemd is distributed in the hope that it will be useful, but
352+ WITHOUT ANY WARRANTY; without even the implied warranty of
353+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
354+ Lesser General Public License for more details.
355+
356+ You should have received a copy of the GNU Lesser General Public License
357+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
358+***/
359+
360+#pragma once
361+
362+#include "config.h"
363+
364+#if HAVE_PRINTF_H
365+#include <printf.h>
366+#else
367+
368+#include <stddef.h>
369+
370+enum { /* C type: */
371+ PA_INT, /* int */
372+ PA_CHAR, /* int, cast to char */
373+ PA_WCHAR, /* wide char */
374+ PA_STRING, /* const char *, a '\0'-terminated string */
375+ PA_WSTRING, /* const wchar_t *, wide character string */
376+ PA_POINTER, /* void * */
377+ PA_FLOAT, /* float */
378+ PA_DOUBLE, /* double */
379+ PA_LAST
380+};
381+
382+/* Flag bits that can be set in a type returned by `parse_printf_format'. */
383+#define PA_FLAG_MASK 0xff00
384+#define PA_FLAG_LONG_LONG (1 << 8)
385+#define PA_FLAG_LONG_DOUBLE PA_FLAG_LONG_LONG
386+#define PA_FLAG_LONG (1 << 9)
387+#define PA_FLAG_SHORT (1 << 10)
388+#define PA_FLAG_PTR (1 << 11)
389+
390+size_t parse_printf_format(const char *fmt, size_t n, int *types);
391+
392+#endif /* HAVE_PRINTF_H */
Andrew Geissler635e0e42020-08-21 15:58:33 -0500393Index: systemd-stable/src/basic/stdio-util.h
394===================================================================
395--- systemd-stable.orig/src/basic/stdio-util.h
396+++ systemd-stable/src/basic/stdio-util.h
Brad Bishop19323692019-04-05 15:28:33 -0400397@@ -1,13 +1,13 @@
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800398 /* SPDX-License-Identifier: LGPL-2.1+ */
399 #pragma once
400
401-#include <printf.h>
402 #include <stdarg.h>
403 #include <stdio.h>
404 #include <sys/types.h>
405
406 #include "macro.h"
Brad Bishopc342db32019-05-15 21:57:59 -0400407 #include "memory-util.h"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800408+#include "parse-printf-format.h"
409
410 #define snprintf_ok(buf, len, fmt, ...) \
411 ((size_t) snprintf(buf, len, fmt, __VA_ARGS__) < (len))
Andrew Geissler635e0e42020-08-21 15:58:33 -0500412Index: systemd-stable/src/journal/journal-send.c
413===================================================================
414--- systemd-stable.orig/src/journal/journal-send.c
415+++ systemd-stable/src/journal/journal-send.c
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800416@@ -2,7 +2,6 @@
417
418 #include <errno.h>
419 #include <fcntl.h>
420-#include <printf.h>
421 #include <stddef.h>
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800422 #include <sys/un.h>
Andrew Geissler82c905d2020-04-13 13:39:40 -0500423 #include <unistd.h>
Andrew Geissler635e0e42020-08-21 15:58:33 -0500424@@ -21,6 +20,7 @@
Brad Bishopc342db32019-05-15 21:57:59 -0400425 #include "stdio-util.h"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800426 #include "string-util.h"
Brad Bishop19323692019-04-05 15:28:33 -0400427 #include "tmpfile-util.h"
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800428+#include "parse-printf-format.h"
429
430 #define SNDBUF_SIZE (8*1024*1024)
431