File aspell-CVE-2019-20433.patch of Package aspell.20679
Index: aspell-0.60.6.1/auto/MkSrc/CcHelper.pm
===================================================================
--- aspell-0.60.6.1.orig/auto/MkSrc/CcHelper.pm 2011-07-02 23:09:08.000000000 +0200
+++ aspell-0.60.6.1/auto/MkSrc/CcHelper.pm 2020-01-30 11:39:17.172960433 +0100
@@ -10,8 +10,8 @@ BEGIN {
use Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(to_c_return_type c_error_cond
- to_type_name make_desc make_func call_func
- make_c_method call_c_method form_c_method
+ to_type_name make_desc make_func call_func get_c_func_name
+ make_c_method make_wide_macro call_c_method form_c_method
make_cxx_method);
}
@@ -90,6 +90,69 @@ sub make_func ( $ \@ $ ; \% ) {
')'));
}
+=item make_wide_version NAME @TYPES PARMS ; %ACCUM
+
+Creates the wide character version of the function if needed
+
+=cut
+
+sub make_wide_version ( $ \@ $ ; \% ) {
+ my ($name, $d, $p, $accum) = @_;
+ my @d = @$d;
+ shift @d;
+ return '' unless grep {$_->{type} eq 'encoded string'} @d;
+ $accum->{sys_headers}{'stddef.h'} = true;
+ $accum->{suffix}[5] = <<'---';
+
+/******************* private implemantion details *********************/
+
+#ifdef __cplusplus
+# define aspell_cast_(type, expr) (static_cast<type>(expr))
+# define aspell_cast_from_wide_(str) (static_cast<const void *>(str))
+#else
+# define aspell_cast_(type, expr) ((type)(expr))
+# define aspell_cast_from_wide_(str) ((const char *)(str))
+#endif
+---
+ my @parms = map {$_->{type} eq 'encoded string'
+ ? ($_->{name}, $_->{name}.'_size')
+ : $_->{name}} @d;
+ $name = to_lower $name;
+ $accum->{suffix}[0] = <<'---';
+/**********************************************************************/
+
+#ifdef ASPELL_ENCODE_SETTING_SECURE
+---
+ $accum->{suffix}[2] = "#endif\n";
+ my @args = map {$_->{type} eq 'encoded string'
+ ? ($_->{name}, "$_->{name}_size", '-1')
+ : $_->{name}} @d;
+ $accum->{suffix}[1] .=
+ (join '',
+ "#define $name",
+ '(', join(', ', @parms), ')',
+ "\\\n ",
+ $name, '_wide',
+ '(', join(', ', @args), ')',
+ "\n");
+ @args = map {$_->{type} eq 'encoded string'
+ ? ("aspell_cast_from_wide_($_->{name})",
+ "$_->{name}_size*aspell_cast_(int,sizeof(*($_->{name})))",
+ "sizeof(*($_->{name}))")
+ : $_->{name}} @d;
+ return (join '',
+ "\n",
+ "/* version of $name that is safe to use with (null terminated) wide characters */\n",
+ '#define ',
+ $name, '_w',
+ '(', join(', ', @parms), ')',
+ "\\\n ",
+ $name, '_wide',
+ '(', join(', ', @args), ')',
+ "\n");
+}
+
+
=item call_func NAME @TYPES PARMS ; %ACCUM
Return a string to call a func. Will prefix the function with return
@@ -103,7 +166,6 @@ Parms can be any of:
sub call_func ( $ \@ $ ; \% ) {
my ($name, $d, $p, $accum) = @_;
- $accum = {} unless defined $accum;
my @d = @$d;
my $func_ret = to_type_name(shift @d, {%$p,pos=>'return'}, %$accum);
return (join '',
@@ -148,8 +210,14 @@ sub to_type_name ( $ $ ; \% ) {
my $name = $t->{name};
my $type = $t->{type};
- return ( (to_type_name {%$d, type=>'string'}, $p, %$accum) ,
- (to_type_name {%$d, type=>'int', name=>"$d->{name}_size"}, $p, %$accum) )
+ if ($name eq 'encoded string' && $is_cc && $pos eq 'parm') {
+ my @types = ((to_type_name {%$d, type=>($p->{wide}?'const void pointer':'string')}, $p, %$accum),
+ (to_type_name {%$d, type=>'int', name=>"$d->{name}_size"}, $p, %$accum));
+ push @types, (to_type_name {%$d, type=>'int', name=>"$d->{name}_type_width"}, $p, %$accum) if $p->{wide};
+ return @types;
+ }
+ return ( (to_type_name {%$d, type=>($p->{wide}?'const void pointer':'string')}, $p, %$accum) ,
+ (to_type_name {%$d, type=>'int', name=>"$d->{name}_size"}, $p, %$accum) )
if $name eq 'encoded string' && $is_cc && $pos eq 'parm';
my $str;
@@ -174,7 +242,7 @@ sub to_type_name ( $ $ ; \% ) {
$str .= "String";
}
} elsif ($name eq 'encoded string') {
- $str .= "const char *";
+ $str .= $p->{wide} ? "const void *" : "const char *";
} elsif ($name eq '') {
$str .= "void";
} elsif ($name eq 'bool' && $is_cc) {
@@ -186,7 +254,7 @@ sub to_type_name ( $ $ ; \% ) {
if ($t->{pointer}) {
$accum->{types}->{$name} = $t;
} else {
- $accum->{headers}->{$t->{created_in}} = true;
+ $accum->{headers}->{$t->{created_in}} = true unless $mode eq 'cc';
}
$str .= "$c_type Aspell" if $mode eq 'cc';
$str .= to_mixed($name);
@@ -214,6 +282,7 @@ sub to_type_name ( $ $ ; \% ) {
return $str;
}
+
=item make_desc DESC ; LEVEL
Make a C comment out of DESC optionally indenting it LEVEL spaces.
@@ -286,6 +355,7 @@ sub form_c_method ($ $ $ ; \% )
} else {
$func = "aspell $class $name";
}
+ $func .= " wide" if $p->{wide};
if (exists $d->{'const'}) {
splice @data, 1, 0, {type => "const $class", name=> $this_name};
} else {
@@ -306,6 +376,21 @@ sub make_c_method ($ $ $ ; \%)
return &make_func(@ret);
}
+sub get_c_func_name ($ $ $)
+{
+ my @ret = &form_c_method(@_);
+ return undef unless @ret > 0;
+ return to_lower $ret[0];
+}
+
+sub make_wide_macro ($ $ $ ; \%)
+{
+ my @ret = &form_c_method(@_);
+ return undef unless @ret > 0;
+ my $str = &make_wide_version(@ret);
+ return $str;
+}
+
sub call_c_method ($ $ $ ; \%)
{
my @ret = &form_c_method(@_);
Index: aspell-0.60.6.1/auto/MkSrc/Create.pm
===================================================================
--- aspell-0.60.6.1.orig/auto/MkSrc/Create.pm 2011-07-02 23:09:08.000000000 +0200
+++ aspell-0.60.6.1/auto/MkSrc/Create.pm 2020-01-30 11:39:17.172960433 +0100
@@ -75,8 +75,10 @@ sub create_cc_file ( % ) {
$file .= "#include \"aspell.h\"\n" if $p{type} eq 'cxx';
$file .= "#include \"settings.h\"\n" if $p{type} eq 'native_impl' && $p{name} eq 'errors';
$file .= "#include \"gettext.h\"\n" if $p{type} eq 'native_impl' && $p{name} eq 'errors';
+ $file .= cmap {"#include <$_>\n"} sort keys %{$accum{sys_headers}};
$file .= cmap {"#include \"".to_lower($_).".hpp\"\n"} sort keys %{$accum{headers}};
- $file .= "#ifdef __cplusplus\nextern \"C\" {\n#endif\n" if $p{header} && !$p{cxx};
+ $file .= "\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n" if $p{header} && !$p{cxx};
+ $file .= join('', grep {defined $_} @{$accum{prefix}});
$file .= "\nnamespace $p{namespace} {\n\n" if $p{cxx};
if (defined $info{forward}{proc}{$p{type}}) {
my @types = sort {$a->{name} cmp $b->{name}} (values %{$accum{types}});
@@ -84,6 +86,7 @@ sub create_cc_file ( % ) {
}
$file .= "\n";
$file .= $body;
+ $file .= join('', grep {defined $_} @{$accum{suffix}});
$file .= "\n\n}\n\n" if $p{cxx};
$file .= "#ifdef __cplusplus\n}\n#endif\n" if $p{header} && !$p{cxx};
$file .= "#endif /* $hm */\n" if $p{header};
Index: aspell-0.60.6.1/auto/MkSrc/Info.pm
===================================================================
--- aspell-0.60.6.1.orig/auto/MkSrc/Info.pm 2011-07-02 23:09:08.000000000 +0200
+++ aspell-0.60.6.1/auto/MkSrc/Info.pm 2020-01-30 11:39:17.172960433 +0100
@@ -60,6 +60,7 @@ each proc sub should take the following
the object from which it is a member of
no native: do not attemt to create a native implementation
treat as object: treat as a object rather than a pointer
+ no conv: do not converted an encoded string
The %info structure is initialized as follows:
@@ -104,8 +105,8 @@ The %info structure is initialized as fo
errors => {}, # possible errors
method => {
# A class method
- options => ['desc', 'posib err', 'c func', 'const',
- 'c only', 'c impl', 'cxx impl'],
+ options => ['desc', 'posib err', 'c func', 'const', 'no conv', 'on conv error',
+ 'c only', 'c impl', 'cxx impl', 'cc extra'],
groups => undef},
constructor => {
# A class constructor
Index: aspell-0.60.6.1/auto/MkSrc/ProcCc.pm
===================================================================
--- aspell-0.60.6.1.orig/auto/MkSrc/ProcCc.pm 2011-07-02 23:09:08.000000000 +0200
+++ aspell-0.60.6.1/auto/MkSrc/ProcCc.pm 2020-01-30 11:39:17.172960433 +0100
@@ -23,7 +23,7 @@ use MkSrc::Info;
sub make_c_object ( $ @ );
$info{group}{proc}{cc} = sub {
- my ($data) = @_;
+ my ($data,@rest) = @_;
my $ret;
my $stars = (70 - length $data->{name})/2;
$ret .= "/";
@@ -33,14 +33,14 @@ $info{group}{proc}{cc} = sub {
$ret .= "/\n";
foreach my $d (@{$data->{data}}) {
$ret .= "\n\n";
- $ret .= $info{$d->{type}}{proc}{cc}->($d);
+ $ret .= $info{$d->{type}}{proc}{cc}->($d,@rest);
}
$ret .= "\n\n";
return $ret;
};
$info{enum}{proc}{cc} = sub {
- my ($d) = @_;
+ my ($d,@rest) = @_;
my $n = "Aspell".to_mixed($d->{name});
return ("\n".
make_desc($d->{desc}).
@@ -58,21 +58,26 @@ $info{struct}{proc}{cc} = sub {
};
$info{union}{proc}{cc} = sub {
- return make_c_object "union", $_[0];
+ return make_c_object "union", @_;
};
$info{class}{proc}{cc} = sub {
- my ($d) = @_;
+ my ($d,$accum) = @_;
my $class = $d->{name};
my $classname = "Aspell".to_mixed($class);
my $ret = "";
$ret .= "typedef struct $classname $classname;\n\n";
foreach (@{$d->{data}}) {
- my $s = make_c_method($class, $_, {mode=>'cc'});
+ my $s = make_c_method($class, $_, {mode=>'cc'}, %$accum);
next unless defined $s;
$ret .= "\n";
$ret .= make_desc($_->{desc});
- $ret .= make_c_method($class, $_, {mode=>'cc'}).";\n";
+ $ret .= make_c_method($class, $_, {mode=>'cc'}, %$accum).";\n";
+ if (grep {$_->{type} eq 'encoded string'} @{$_->{data}}) {
+ $ret .= make_c_method($class, $_, {mode=>'cc', wide=>true}, %$accum).";\n";
+ $ret .= make_wide_macro($class, $_, {mode=>'cc'}, %$accum);
+ }
+ $ret .= "\n".$_->{'cc extra'}."\n" if defined $_->{'cc extra'};
}
$ret .= "\n";
return $ret;
@@ -105,7 +110,8 @@ $info{errors}{proc}{cc} = sub {
};
sub make_c_object ( $ @ ) {
- my ($t, $d) = @_;
+ my ($t, $d, $accum) = @_;
+ $accum = {} unless defined $accum;
my $struct;
$struct .= "Aspell";
$struct .= to_mixed($d->{name});
@@ -120,7 +126,7 @@ sub make_c_object ( $ @ ) {
"\n};\n"),
"typedef $t $struct $struct;",
join ("\n",
- map {make_c_method($d->{name}, $_, {mode=>'cc'}).";"}
+ map {make_c_method($d->{name}, $_, {mode=>'cc'}, %$accum).";"}
grep {$_->{type} eq 'method'}
@{$d->{data}})
)."\n";
Index: aspell-0.60.6.1/auto/MkSrc/ProcImpl.pm
===================================================================
--- aspell-0.60.6.1.orig/auto/MkSrc/ProcImpl.pm 2011-07-02 23:09:08.000000000 +0200
+++ aspell-0.60.6.1/auto/MkSrc/ProcImpl.pm 2020-01-30 11:39:17.172960433 +0100
@@ -45,10 +45,13 @@ $info{class}{proc}{impl} = sub {
foreach (grep {$_ ne ''} split /\s*,\s*/, $data->{'c impl headers'}) {
$accum->{headers}{$_} = true;
}
- foreach my $d (@{$data->{data}}) {
+ my @d = @{$data->{data}};
+ while (@d) {
+ my $d = shift @d;
+ my $need_wide = false;
next unless one_of $d->{type}, qw(method constructor destructor);
my @parms = @{$d->{data}} if exists $d->{data};
- my $m = make_c_method $data->{name}, $d, {mode=>'cc_cxx', use_name=>true}, %$accum;
+ my $m = make_c_method $data->{name}, $d, {mode=>'cc_cxx', use_name=>true, wide=>$d->{wide}}, %$accum;
next unless defined $m;
$ret .= "extern \"C\" $m\n";
$ret .= "{\n";
@@ -57,24 +60,49 @@ $info{class}{proc}{impl} = sub {
} else {
if ($d->{type} eq 'method') {
my $ret_type = shift @parms;
- my $ret_native = to_type_name $ret_type, {mode=>'native_no_err', pos=>'return'}, %$accum;
+ my $ret_native = to_type_name $ret_type, {mode=>'native_no_err', pos=>'return', wide=>$d->{wide}}, %$accum;
my $snum = 0;
+ my $call_fun = $d->{name};
+ my @call_parms;
foreach (@parms) {
my $n = to_lower($_->{name});
- if ($_->{type} eq 'encoded string') {
- $accum->{headers}{'mutable string'} = true;
- $accum->{headers}{'convert'} = true;
- $ret .= " ths->temp_str_$snum.clear();\n";
- $ret .= " ths->to_internal_->convert($n, ${n}_size, ths->temp_str_$snum);\n";
- $ret .= " unsigned int s$snum = ths->temp_str_$snum.size();\n";
- $_ = "MutableString(ths->temp_str_$snum.mstr(), s$snum)";
- $snum++;
+ if ($_->{type} eq 'encoded string' && !exists($d->{'no conv'})) {
+ $need_wide = true unless $d->{wide};
+ die unless exists $d->{'posib err'};
+ $accum->{headers}{'mutable string'} = true;
+ $accum->{headers}{'convert'} = true;
+ my $name = get_c_func_name $data->{name}, $d, {mode=>'cc_cxx', use_name=>true, wide=>$d->{wide}};
+ $ret .= " ths->temp_str_$snum.clear();\n";
+ if ($d->{wide}) {
+ $ret .= " ${n}_size = get_correct_size(\"$name\", ths->to_internal_->in_type_width(), ${n}_size, ${n}_type_width);\n";
+ } else {
+ $ret .= " PosibErr<int> ${n}_fixed_size = get_correct_size(\"$name\", ths->to_internal_->in_type_width(), ${n}_size);\n";
+ if (exists($d->{'on conv error'})) {
+ $ret .= " if (${n}_fixed_size.get_err()) {\n";
+ $ret .= " ".$d->{'on conv error'}."\n";
+ $ret .= " } else {\n";
+ $ret .= " ${n}_size = ${n}_fixed_size;\n";
+ $ret .= " }\n";
+ } else {
+ $ret .= " ths->err_.reset(${n}_fixed_size.release_err());\n";
+ $ret .= " if (ths->err_ != 0) return ".(c_error_cond $ret_type).";\n";
+ }
+ }
+ $ret .= " ths->to_internal_->convert($n, ${n}_size, ths->temp_str_$snum);\n";
+ $ret .= " unsigned int s$snum = ths->temp_str_$snum.size();\n";
+ push @call_parms, "MutableString(ths->temp_str_$snum.mstr(), s$snum)";
+ $snum++;
+ } elsif ($_->{type} eq 'encoded string') {
+ $need_wide = true unless $d->{wide};
+ push @call_parms, $n, "${n}_size";
+ push @call_parms, "${n}_type_width" if $d->{wide};
+ $call_fun .= " wide" if $d->{wide};
} else {
- $_ = $n;
+ push @call_parms, $n;
}
}
- my $parms = '('.(join ', ', @parms).')';
- my $exp = "ths->".to_lower($d->{name})."$parms";
+ my $parms = '('.(join ', ', @call_parms).')';
+ my $exp = "ths->".to_lower($call_fun)."$parms";
if (exists $d->{'posib err'}) {
$accum->{headers}{'posib err'} = true;
$ret .= " PosibErr<$ret_native> ret = $exp;\n";
@@ -118,6 +146,7 @@ $info{class}{proc}{impl} = sub {
}
}
$ret .= "}\n\n";
+ unshift @d,{%$d, wide=>true} if $need_wide;
}
return $ret;
};
Index: aspell-0.60.6.1/auto/MkSrc/Read.pm
===================================================================
--- aspell-0.60.6.1.orig/auto/MkSrc/Read.pm 2011-07-02 23:09:08.000000000 +0200
+++ aspell-0.60.6.1/auto/MkSrc/Read.pm 2020-01-30 11:39:17.172960433 +0100
@@ -88,13 +88,13 @@ sub advance ( ) {
$in_pod = $1 if $line =~ /^\=(\w+)/;
$line = '' if $in_pod;
$in_pod = undef if $in_pod && $in_pod eq 'cut';
- $line =~ s/\#.*$//;
+ $line =~ s/(?<!\\)\#.*$//;
$line =~ s/^(\t*)//;
$level = $base_level + length($1);
$line =~ s/\s*$//;
++$base_level if $line =~ s/^\{$//;
--$base_level if $line =~ s/^\}$//;
- $line =~ s/\\([{}])/$1/g;
+ $line =~ s/\\([{}#\\])/$1/g;
} while ($line eq '');
#print "$level:$line\n";
}
Index: aspell-0.60.6.1/auto/mk-src.in
===================================================================
--- aspell-0.60.6.1.orig/auto/mk-src.in 2011-07-02 23:09:08.000000000 +0200
+++ aspell-0.60.6.1/auto/mk-src.in 2020-01-30 11:39:17.172960433 +0100
@@ -599,6 +599,7 @@ errors:
invalid expression
mesg => "%expression" is not a valid regular expression.
parms => expression
+
}
group: speller
{
@@ -641,6 +642,7 @@ class: speller
posib err
desc => Returns 0 if it is not in the dictionary,
1 if it is, or -1 on error.
+ on conv error => return 0;
/
bool
encoded string: word
@@ -706,6 +708,8 @@ class: speller
desc => Return NULL on error.
The word list returned by suggest is only
valid until the next call to suggest.
+ on conv error =>
+ word = NULL; word_size = 0;
/
const word list
encoded string: word
@@ -831,7 +835,6 @@ class: document checker
void
method: process
-
desc => Process a string.
The string passed in should only be split on
white space characters. Furthermore, between
@@ -840,10 +843,10 @@ class: document checker
in the document. Passing in strings out of
order, skipping strings or passing them in
more than once may lead to undefined results.
+ no conv
/
void
- string: str
- int: size
+ encoded string: str
method: next misspelling
@@ -851,9 +854,23 @@ class: document checker
processed string. If there are no more
misspelled words, then token.word will be
NULL and token.size will be 0
+ cc extra =>
+ \#define aspell_document_checker_next_misspelling_w(type, ths) \\
+ aspell_document_checker_next_misspelling_adj(ths, sizeof(type))
/
token object
+ method: next misspelling adj
+ desc => internal: do not use
+ c impl =>
+ Token res = ths->next_misspelling();
+ res.offset /= type_width;
+ res.len /= type_width;
+ return res;
+ /
+ token object
+ int: type_width
+
method: filter
desc => Returns the underlying filter class.
@@ -913,9 +930,30 @@ class: string enumeration
ths->from_internal_->append_null(ths->temp_str);
return ths->temp_str.data();
\}
+ cc extra =>
+ \#define aspell_string_enumeration_next_w(type, ths) \\
+ aspell_cast_(const type *, aspell_string_enumeration_next_wide(ths, sizeof(type)))
/
const string
+ method: next wide
+ c impl =>
+ const char * s = ths->next();
+ if (s == 0) {
+ return s;
+ } else if (ths->from_internal_ == 0) \{
+ assert(type_width == 1);
+ return s;
+ \} else \{
+ assert(type_width == ths->from_internal_->out_type_width());
+ ths->temp_str.clear();
+ ths->from_internal_->convert(s,-1,ths->temp_str);
+ ths->from_internal_->append_null(ths->temp_str);
+ return ths->temp_str.data();
+ \}
+ /
+ const void pointer
+ int: type_width
}
group: info
{
Index: aspell-0.60.6.1/common/convert.cpp
===================================================================
--- aspell-0.60.6.1.orig/common/convert.cpp 2020-01-30 11:39:17.136960213 +0100
+++ aspell-0.60.6.1/common/convert.cpp 2020-01-30 11:39:17.172960433 +0100
@@ -511,18 +511,25 @@ namespace acommon {
// Trivial Conversion
//
+ const char * unsupported_null_term_wide_string_msg =
+ "Null-terminated wide-character strings unsupported when used this way.";
+
template <typename Chr>
struct DecodeDirect : public Decode
{
+ DecodeDirect() {type_width = sizeof(Chr);}
void decode(const char * in0, int size, FilterCharVector & out) const {
const Chr * in = reinterpret_cast<const Chr *>(in0);
- if (size == -1) {
+ if (size == -sizeof(Chr)) {
for (;*in; ++in)
- out.append(*in);
+ out.append(*in, sizeof(Chr));
+ } else if (size <= -1) {
+ fprintf(stderr, "%s\n", unsupported_null_term_wide_string_msg);
+ abort();
} else {
- const Chr * stop = reinterpret_cast<const Chr *>(in0 +size);
+ const Chr * stop = reinterpret_cast<const Chr *>(in0) + size/sizeof(Chr);
for (;in != stop; ++in)
- out.append(*in);
+ out.append(*in, sizeof(Chr));
}
}
PosibErr<void> decode_ec(const char * in0, int size,
@@ -535,6 +542,7 @@ namespace acommon {
template <typename Chr>
struct EncodeDirect : public Encode
{
+ EncodeDirect() {type_width = sizeof(Chr);}
void encode(const FilterChar * in, const FilterChar * stop,
CharVector & out) const {
for (; in != stop; ++in) {
@@ -564,11 +572,15 @@ namespace acommon {
template <typename Chr>
struct ConvDirect : public DirectConv
{
+ ConvDirect() {type_width = sizeof(Chr);}
void convert(const char * in0, int size, CharVector & out) const {
- if (size == -1) {
+ if (size == -sizeof(Chr)) {
const Chr * in = reinterpret_cast<const Chr *>(in0);
for (;*in != 0; ++in)
out.append(in, sizeof(Chr));
+ } else if (size <= -1) {
+ fprintf(stderr, "%s\n", unsupported_null_term_wide_string_msg);
+ abort();
} else {
out.append(in0, size);
}
@@ -1092,5 +1104,20 @@ namespace acommon {
}
return 0;
}
-
+
+ PosibErr<void> unsupported_null_term_wide_string_err_(const char * func) {
+ static bool reported_to_stderr = false;
+ PosibErr<void> err = make_err(other_error, unsupported_null_term_wide_string_msg);
+ if (!reported_to_stderr) {
+ CERR.printf("ERROR: %s: %s\n", func, unsupported_null_term_wide_string_msg);
+ reported_to_stderr = true;
+ }
+ return err;
+ }
+
+ void unsupported_null_term_wide_string_abort_(const char * func) {
+ CERR.printf("%s: %s\n", unsupported_null_term_wide_string_msg);
+ abort();
+ }
+
}
Index: aspell-0.60.6.1/common/convert.hpp
===================================================================
--- aspell-0.60.6.1.orig/common/convert.hpp 2011-07-02 23:09:08.000000000 +0200
+++ aspell-0.60.6.1/common/convert.hpp 2020-01-30 11:39:17.172960433 +0100
@@ -7,6 +7,8 @@
#ifndef ASPELL_CONVERT__HPP
#define ASPELL_CONVERT__HPP
+#include "settings.h"
+
#include "string.hpp"
#include "posib_err.hpp"
#include "char_vector.hpp"
@@ -25,8 +27,9 @@ namespace acommon {
typedef const Config CacheConfig;
typedef const char * CacheKey;
String key;
+ int type_width; // type width in bytes
bool cache_key_eq(const char * l) const {return key == l;}
- ConvBase() {}
+ ConvBase() : type_width(1) {}
private:
ConvBase(const ConvBase &);
void operator=(const ConvBase &);
@@ -56,6 +59,8 @@ namespace acommon {
virtual ~Encode() {}
};
struct DirectConv { // convert directly from in_code to out_code.
+ int type_width; // type width in bytes
+ DirectConv() : type_width(1) {}
// should not take ownership of decode and encode.
// decode and encode guaranteed to stick around for the life
// of the object.
@@ -126,6 +131,9 @@ namespace acommon {
const char * in_code() const {return decode_->key.c_str();}
const char * out_code() const {return encode_->key.c_str();}
+ int in_type_width() const {return decode_->type_width;}
+ int out_type_width() const {return encode_->type_width;}
+
void append_null(CharVector & out) const
{
const char nul[4] = {0,0,0,0}; // 4 should be enough
@@ -191,6 +199,10 @@ namespace acommon {
}
}
+ void convert(const void * in, int size, CharVector & out) {
+ convert(static_cast<const char *>(in), size, out);
+ }
+
void generic_convert(const char * in, int size, CharVector & out);
};
@@ -412,6 +424,30 @@ namespace acommon {
return operator()(str, str + byte_size);}
};
+#ifdef SLOPPY_NULL_TERM_STRINGS
+ static const bool sloppy_null_term_strings = true;
+#else
+ static const bool sloppy_null_term_strings = false;
+#endif
+
+ PosibErr<void> unsupported_null_term_wide_string_err_(const char * func);
+ void unsupported_null_term_wide_string_abort_(const char * func);
+
+ static inline PosibErr<int> get_correct_size(const char * func, int conv_type_width, int size) {
+ if (sloppy_null_term_strings && size <= -1)
+ return -conv_type_width;
+ if (size <= -1 && -conv_type_width != size)
+ return unsupported_null_term_wide_string_err_(func);
+ return size;
+ }
+ static inline int get_correct_size(const char * func, int conv_type_width, int size, int type_width) {
+ if ((sloppy_null_term_strings || type_width <= -1) && size <= -1)
+ return -conv_type_width;
+ if (size <= -1 && conv_type_width != type_width)
+ unsupported_null_term_wide_string_abort_(func);
+ return size;
+ }
+
}
#endif
Index: aspell-0.60.6.1/common/document_checker.cpp
===================================================================
--- aspell-0.60.6.1.orig/common/document_checker.cpp 2004-12-03 03:22:16.000000000 +0100
+++ aspell-0.60.6.1/common/document_checker.cpp 2020-01-30 11:39:17.172960433 +0100
@@ -44,7 +44,9 @@ namespace acommon {
void DocumentChecker::process(const char * str, int size)
{
proc_str_.clear();
- conv_->decode(str, size, proc_str_);
+ PosibErr<int> fixed_size = get_correct_size("aspell_document_checker_process", conv_->in_type_width(), size);
+ if (!fixed_size.has_err())
+ conv_->decode(str, fixed_size, proc_str_);
proc_str_.append(0);
FilterChar * begin = proc_str_.pbegin();
FilterChar * end = proc_str_.pend() - 1;
@@ -53,6 +55,19 @@ namespace acommon {
tokenizer_->reset(begin, end);
}
+ void DocumentChecker::process_wide(const void * str, int size, int type_width)
+ {
+ proc_str_.clear();
+ int fixed_size = get_correct_size("aspell_document_checker_process", conv_->in_type_width(), size, type_width);
+ conv_->decode(static_cast<const char *>(str), fixed_size, proc_str_);
+ proc_str_.append(0);
+ FilterChar * begin = proc_str_.pbegin();
+ FilterChar * end = proc_str_.pend() - 1;
+ if (filter_)
+ filter_->process(begin, end);
+ tokenizer_->reset(begin, end);
+ }
+
Token DocumentChecker::next_misspelling()
{
bool correct;
Index: aspell-0.60.6.1/common/document_checker.hpp
===================================================================
--- aspell-0.60.6.1.orig/common/document_checker.hpp 2002-08-10 17:17:06.000000000 +0200
+++ aspell-0.60.6.1/common/document_checker.hpp 2020-01-30 11:39:17.176960457 +0100
@@ -36,6 +36,7 @@ namespace acommon {
PosibErr<void> setup(Tokenizer *, Speller *, Filter *);
void reset();
void process(const char * str, int size);
+ void process_wide(const void * str, int size, int type_width);
Token next_misspelling();
Filter * filter() {return filter_;}
Index: aspell-0.60.6.1/configure.ac
===================================================================
--- aspell-0.60.6.1.orig/configure.ac 2020-01-30 11:39:17.148960287 +0100
+++ aspell-0.60.6.1/configure.ac 2020-01-30 11:39:17.176960457 +0100
@@ -70,6 +70,9 @@ AC_ARG_ENABLE(compile-in-filters,
AC_ARG_ENABLE(filter-version-control,
[ --disable-filter-version-control])
+AC_ARG_ENABLE(sloppy-null-term-strings,
+ AS_HELP_STRING([--enable-sloppy-null-term-strings],[allows allow null terminated UCS-2 and UCS-4 strings]))
+
AC_ARG_ENABLE(pspell-compatibility,
AS_HELP_STRING([--disable-pspell-compatibility],[don't install pspell compatibility libraries]))
@@ -133,6 +136,11 @@ fi
AM_CONDITIONAL(COMPILE_IN_FILTERS,
[test "$enable_compile_in_filters" = "yes"])
+if test "$enable_sloppy_null_term_strings" = "yes"
+then
+ AC_DEFINE(SLOPPY_NULL_TERM_STRINGS, 1, [Defined if null-terminated UCS-2 and UCS-4 strings should always be allowed.])
+fi
+
AM_CONDITIONAL(PSPELL_COMPATIBILITY,
[test "$enable_pspell_compatibility" != "no"])
AM_CONDITIONAL(INCREMENTED_SONAME,