utf8.c revision 2e3d069236777cd62f755a02f4a239306b4ad21a
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2012 Lennart Poettering
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
/* This file is based on the GLIB utf8 validation functions. The
* original license text follows. */
/* gutf8.c - Operations on UTF-8 strings.
*
* Copyright (C) 1999 Tom Tromey
* Copyright (C) 2000 Red Hat, Inc.
*
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <errno.h>
#include <stdlib.h>
#include <inttypes.h>
#include <string.h>
#include <stdbool.h>
#include "utf8.h"
#include "util.h"
#define FILTER_CHAR '_'
return false;
return false;
return false;
return false;
return true;
}
return false;
return true;
}
*u_ch <<= 6;
}
/*
0 to ' '-1 is the C0 range.
DEL=0x7F, and DEL+1 to 0x9F is C1 range.
'\t' is in C0 range, but more or less harmless and commonly used.
*/
}
const uint8_t *p;
if (*p < 128) {
val = *p;
} else {
if ((*p & 0xe0) == 0xc0) { /* 110xxxxx two-char seq. */
min = 128;
goto ONE_REMAINING;
} else if ((*p & 0xf0) == 0xe0) { /* 1110xxxx three-char seq.*/
goto TWO_REMAINING;
} else if ((*p & 0xf8) == 0xf0) { /* 11110xxx four-char seq */
} else
goto error;
p++;
length--;
if (!length || !is_continuation_char(*p))
goto error;
merge_continuation_char(&val, *p);
p++;
length--;
if (!is_continuation_char(*p))
goto error;
merge_continuation_char(&val, *p);
p++;
length--;
if (!is_continuation_char(*p))
goto error;
merge_continuation_char(&val, *p);
goto error;
}
if (is_unicode_control(val))
goto error;
}
return (char*) str;
return NULL;
}
int size;
uint8_t *o;
if (*p < 128) {
if (o)
*o = *p;
} else {
last = p;
if ((*p & 0xe0) == 0xc0) { /* 110xxxxx two-char seq. */
size = 2;
min = 128;
goto ONE_REMAINING;
} else if ((*p & 0xf0) == 0xe0) { /* 1110xxxx three-char seq.*/
size = 3;
goto TWO_REMAINING;
} else if ((*p & 0xf8) == 0xf0) { /* 11110xxx four-char seq */
size = 4;
} else
goto error;
p++;
if (!is_continuation_char(*p))
goto error;
merge_continuation_char(&val, *p);
p++;
if (!is_continuation_char(*p))
goto error;
merge_continuation_char(&val, *p);
p++;
if (!is_continuation_char(*p))
goto error;
merge_continuation_char(&val, *p);
goto error;
if (!is_unicode_valid(val))
goto error;
if (o) {
o += size;
}
continue;
if (o) {
*o = FILTER_CHAR;
p = last; /* We retry at the next character */
} else
goto failure;
}
if (o)
o++;
}
if (o) {
*o = '\0';
return output;
}
return (char*) str;
return NULL;
}
char* utf8_is_valid (const char *str) {
}
char* utf8_filter (const char *str) {
char *new_str;
if (!new_str)
return NULL;
}
char *ascii_is_valid(const char *str) {
const char *p;
for (p = str; *p; p++)
if ((unsigned char) *p >= 128)
return NULL;
return (char*) str;
}
char *ascii_filter(const char *str) {
const char *s;
char *r, *d;
size_t l;
r = malloc(l + 1);
if (!r)
return NULL;
for (s = str, d = r; *s; s++)
if ((unsigned char) *s < 128)
*(d++) = *s;
*d = 0;
return r;
}
char *r;
const uint8_t *f;
uint8_t *t;
if (!r)
return NULL;
t = (uint8_t*) r;
uint16_t c;
c = (f[1] << 8) | f[0];
if (c == 0) {
*t = 0;
return r;
} else if (c < 0x80) {
*(t++) = (uint8_t) c;
} else if (c < 0x800) {
} else {
}
}
*t = 0;
return r;
}