~ubuntu-branches/debian/jessie/systemd/jessie

« back to all changes in this revision

Viewing changes to src/utf8.c

  • Committer: Package Import Robot
  • Author(s): Tollef Fog Heen, Tollef Fog Heen, Michael Biebl
  • Date: 2012-04-03 19:59:17 UTC
  • mfrom: (1.1.10) (6.1.3 experimental)
  • Revision ID: package-import@ubuntu.com-20120403195917-l532urrbg4pkreas
Tags: 44-1
[ Tollef Fog Heen ]
* New upstream version.
  - Backport 3492207: journal: PAGE_SIZE is not known on ppc and other
    archs
  - Backport 5a2a2a1: journal: react with immediate rotation to a couple
    of more errors
  - Backport 693ce21: util: never follow symlinks in rm_rf_children()
    Fixes CVE-2012-1174, closes: #664364
* Drop output message from init-functions hook, it's pointless.
* Only rmdir /lib/init/rw if it exists.
* Explicitly order debian-fixup before sysinit.target to prevent a
  possible race condition with the creation of sockets.  Thanks to
  Michael Biebl for debugging this.
* Always restart the initctl socket on upgrades, to mask sysvinit
  removing it.

[ Michael Biebl ]
* Remove workaround for non-interactive sessions from pam config again.
* Create compat /dev/initctl symlink in case we are upgrading from a system
  running a newer version of sysvinit (using /run/initctl) and sysvinit is
  replaced with systemd-sysv during the upgrade. Closes: #663219
* Install new man pages.
* Build-Depend on valac (>= 0.12) instead of valac-0.12. Closes: #663323

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
 
2
 
 
3
/***
 
4
  This file is part of systemd.
 
5
 
 
6
  Copyright 2012 Lennart Poettering
 
7
 
 
8
  systemd is free software; you can redistribute it and/or modify it
 
9
  under the terms of the GNU General Public License as published by
 
10
  the Free Software Foundation; either version 2 of the License, or
 
11
  (at your option) any later version.
 
12
 
 
13
  systemd is distributed in the hope that it will be useful, but
 
14
  WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 
16
  General Public License for more details.
 
17
 
 
18
  You should have received a copy of the GNU General Public License
 
19
  along with systemd; If not, see <http://www.gnu.org/licenses/>.
 
20
***/
 
21
 
 
22
/* This file is based on the GLIB utf8 validation functions. The
 
23
 * original license text follows. */
 
24
 
 
25
/* gutf8.c - Operations on UTF-8 strings.
 
26
 *
 
27
 * Copyright (C) 1999 Tom Tromey
 
28
 * Copyright (C) 2000 Red Hat, Inc.
 
29
 *
 
30
 * This library is free software; you can redistribute it and/or
 
31
 * modify it under the terms of the GNU Lesser General Public
 
32
 * License as published by the Free Software Foundation; either
 
33
 * version 2 of the License, or (at your option) any later version.
 
34
 *
 
35
 * This library is distributed in the hope that it will be useful,
 
36
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
37
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
 
38
 * Lesser General Public License for more details.
 
39
 *
 
40
 * You should have received a copy of the GNU Lesser General Public
 
41
 * License along with this library; if not, write to the
 
42
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
43
 * Boston, MA 02111-1307, USA.
 
44
 */
 
45
 
 
46
#include <errno.h>
 
47
#include <stdlib.h>
 
48
#include <inttypes.h>
 
49
#include <string.h>
 
50
#include <stdbool.h>
 
51
 
 
52
#include "utf8.h"
 
53
 
 
54
#define FILTER_CHAR '_'
 
55
 
 
56
static inline bool is_unicode_valid(uint32_t ch) {
 
57
 
 
58
        if (ch >= 0x110000) /* End of unicode space */
 
59
                return false;
 
60
        if ((ch & 0xFFFFF800) == 0xD800) /* Reserved area for UTF-16 */
 
61
                return false;
 
62
        if ((ch >= 0xFDD0) && (ch <= 0xFDEF)) /* Reserved */
 
63
                return false;
 
64
        if ((ch & 0xFFFE) == 0xFFFE) /* BOM (Byte Order Mark) */
 
65
                return false;
 
66
 
 
67
        return true;
 
68
}
 
69
 
 
70
static inline bool is_continuation_char(uint8_t ch) {
 
71
        if ((ch & 0xc0) != 0x80) /* 10xxxxxx */
 
72
                return false;
 
73
        return true;
 
74
}
 
75
 
 
76
static inline void merge_continuation_char(uint32_t *u_ch, uint8_t ch) {
 
77
        *u_ch <<= 6;
 
78
        *u_ch |= ch & 0x3f;
 
79
}
 
80
 
 
81
static char* utf8_validate(const char *str, char *output) {
 
82
        uint32_t val = 0;
 
83
        uint32_t min = 0;
 
84
        const uint8_t *p, *last;
 
85
        int size;
 
86
        uint8_t *o;
 
87
 
 
88
        assert(str);
 
89
 
 
90
        o = (uint8_t*) output;
 
91
        for (p = (const uint8_t*) str; *p; p++) {
 
92
                if (*p < 128) {
 
93
                        if (o)
 
94
                                *o = *p;
 
95
                } else {
 
96
                        last = p;
 
97
 
 
98
                        if ((*p & 0xe0) == 0xc0) { /* 110xxxxx two-char seq. */
 
99
                                size = 2;
 
100
                                min = 128;
 
101
                                val = (uint32_t) (*p & 0x1e);
 
102
                                goto ONE_REMAINING;
 
103
                        } else if ((*p & 0xf0) == 0xe0) { /* 1110xxxx three-char seq.*/
 
104
                                size = 3;
 
105
                                min = (1 << 11);
 
106
                                val = (uint32_t) (*p & 0x0f);
 
107
                                goto TWO_REMAINING;
 
108
                        } else if ((*p & 0xf8) == 0xf0) { /* 11110xxx four-char seq */
 
109
                                size = 4;
 
110
                                min = (1 << 16);
 
111
                                val = (uint32_t) (*p & 0x07);
 
112
                        } else
 
113
                                goto error;
 
114
 
 
115
                        p++;
 
116
                        if (!is_continuation_char(*p))
 
117
                                goto error;
 
118
                        merge_continuation_char(&val, *p);
 
119
 
 
120
                TWO_REMAINING:
 
121
                        p++;
 
122
                        if (!is_continuation_char(*p))
 
123
                                goto error;
 
124
                        merge_continuation_char(&val, *p);
 
125
 
 
126
                ONE_REMAINING:
 
127
                        p++;
 
128
                        if (!is_continuation_char(*p))
 
129
                                goto error;
 
130
                        merge_continuation_char(&val, *p);
 
131
 
 
132
                        if (val < min)
 
133
                                goto error;
 
134
 
 
135
                        if (!is_unicode_valid(val))
 
136
                                goto error;
 
137
 
 
138
                        if (o) {
 
139
                                memcpy(o, last, (size_t) size);
 
140
                                o += size;
 
141
                        }
 
142
 
 
143
                        continue;
 
144
 
 
145
                error:
 
146
                        if (o) {
 
147
                                *o = FILTER_CHAR;
 
148
                                p = last; /* We retry at the next character */
 
149
                        } else
 
150
                                goto failure;
 
151
                }
 
152
 
 
153
                if (o)
 
154
                        o++;
 
155
        }
 
156
 
 
157
        if (o) {
 
158
                *o = '\0';
 
159
                return output;
 
160
        }
 
161
 
 
162
        return (char*) str;
 
163
 
 
164
failure:
 
165
        return NULL;
 
166
}
 
167
 
 
168
char* utf8_is_valid (const char *str) {
 
169
        return utf8_validate(str, NULL);
 
170
}
 
171
 
 
172
char* utf8_filter (const char *str) {
 
173
        char *new_str;
 
174
 
 
175
        assert(str);
 
176
 
 
177
        new_str = malloc(strlen(str) + 1);
 
178
        if (!new_str)
 
179
                return NULL;
 
180
 
 
181
        return utf8_validate(str, new_str);
 
182
}
 
183
 
 
184
char *ascii_is_valid(const char *str) {
 
185
        const char *p;
 
186
 
 
187
        assert(str);
 
188
 
 
189
        for (p = str; *p; p++)
 
190
                if ((unsigned char) *p >= 128)
 
191
                        return NULL;
 
192
 
 
193
        return (char*) str;
 
194
}
 
195
 
 
196
char *ascii_filter(const char *str) {
 
197
        char *r, *s, *d;
 
198
        size_t l;
 
199
 
 
200
        assert(str);
 
201
 
 
202
        l = strlen(str);
 
203
        r = malloc(l + 1);
 
204
        if (!r)
 
205
                return NULL;
 
206
 
 
207
        for (s = r, d = r; *s; s++)
 
208
                if ((unsigned char) *s < 128)
 
209
                        *(d++) = *s;
 
210
 
 
211
        *d = 0;
 
212
 
 
213
        return r;
 
214
}