diff --git a/CVE-2019-17544.patch b/CVE-2019-17544.patch new file mode 100644 index 0000000000000000000000000000000000000000..69f3045817df1f3879843bdd0b92e72b783520ba --- /dev/null +++ b/CVE-2019-17544.patch @@ -0,0 +1,49 @@ +From 80fa26c74279fced8d778351cff19d1d8f44fe4e Mon Sep 17 00:00:00 2001 +From: Kevin Atkinson +Date: Sun, 4 Aug 2019 04:20:29 -0400 +Subject: [PATCH] Fix various bugs found by OSS-Fuze. + +--- + common/config.cpp | 2 +- + common/file_util.cpp | 1 + + common/getdata.cpp | 2 +- + 3 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/common/config.cpp b/common/config.cpp +index 017e741..e117d3c 100644 +--- a/common/config.cpp ++++ b/common/config.cpp +@@ -763,7 +763,7 @@ namespace acommon { + } + res.append(':'); + } +- if (res.back() == ':') res.pop_back(); ++ if (!res.empty() && res.back() == ':') res.pop_back(); + } + + struct ListAddHelper : public AddableContainer +diff --git a/common/file_util.cpp b/common/file_util.cpp +index 8515832..56ea501 100644 +--- a/common/file_util.cpp ++++ b/common/file_util.cpp +@@ -181,6 +181,7 @@ namespace acommon { + while ( (dir = els.next()) != 0 ) + { + path = dir; ++ if (path.empty()) continue; + if (path.back() != '/') path += '/'; + unsigned dir_len = path.size(); + path += filename; +diff --git a/common/getdata.cpp b/common/getdata.cpp +index 7e822c9..1b04823 100644 +--- a/common/getdata.cpp ++++ b/common/getdata.cpp +@@ -64,7 +64,7 @@ namespace acommon { + char * unescape(char * dest, const char * src) + { + while (*src) { +- if (*src == '\\') { ++ if (*src == '\\' && src[1]) { + ++src; + switch (*src) { + case 'n': *dest = '\n'; break; diff --git a/CVE-2019-20433-1.patch b/CVE-2019-20433-1.patch new file mode 100644 index 0000000000000000000000000000000000000000..e4d47555a1e473815c7b5af2f0a805203ce46a51 --- /dev/null +++ b/CVE-2019-20433-1.patch @@ -0,0 +1,1207 @@ +From de29341638833ba7717bd6b5e6850998454b044b Mon Sep 17 00:00:00 2001 +From: Kevin Atkinson +Date: Sat, 17 Aug 2019 17:06:53 -0400 +Subject: [PATCH] Don't allow null-terminated UCS-2/4 strings using the + original API. + +Detect if the encoding is UCS-2/4 and the length is -1 in affected API +functions and refuse to convert the string. If the string ends up +being converted somehow, abort with an error message in DecodeDirect +and ConvDirect. To convert a null terminated string in +Decode/ConvDirect, a negative number corresponding to the width of the +underlying character type for the encoding is expected; for example, +if the encoding is "ucs-2" then a the size is expected to be -2. + +Also fix a 1-3 byte over-read in DecodeDirect when reading UCS-2/4 +strings when a size is provided (found by OSS-Fuzz). + +Also fix a bug in DecodeDirect that caused DocumentChecker to return +the wrong offsets when working with UCS-2/4 strings. +--- + auto/MkSrc/CcHelper.pm | 99 ++++++++++++++++++++++++++++++++++--- + auto/MkSrc/Create.pm | 5 +- + auto/MkSrc/Info.pm | 5 +- + auto/MkSrc/ProcCc.pm | 24 +++++---- + auto/MkSrc/ProcImpl.pm | 57 +++++++++++++++------ + auto/MkSrc/Read.pm | 4 +- + auto/mk-src.in | 44 +++++++++++++++-- + common/convert.cpp | 39 ++++++++++++--- + common/convert.hpp | 38 +++++++++++++- + common/document_checker.cpp | 17 ++++++- + common/document_checker.hpp | 1 + + configure.ac | 8 +++ + manual/aspell.texi | 58 ++++++++++++++++------ + manual/readme.texi | 67 +++++++++++++++++++++---- + test/cxx_warnings_test.cpp | 84 +++++++++++++++++++++++++++++++ + test/wide_test_invalid.c | 69 ++++++++++++++++++++++++++ + test/wide_test_valid.c | 69 ++++++++++++++++++++++++++ + 17 files changed, 618 insertions(+), 70 deletions(-) + create mode 100644 test/cxx_warnings_test.cpp + create mode 100644 test/wide_test_invalid.c + create mode 100644 test/wide_test_valid.c + +diff --git a/auto/MkSrc/CcHelper.pm b/auto/MkSrc/CcHelper.pm +index e814a1a..9a96041 100644 +--- a/auto/MkSrc/CcHelper.pm ++++ b/auto/MkSrc/CcHelper.pm +@@ -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(expr)) ++# define aspell_cast_from_wide_(str) (static_cast(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(@_); +diff --git a/auto/MkSrc/Create.pm b/auto/MkSrc/Create.pm +index e467a10..d76af15 100644 +--- a/auto/MkSrc/Create.pm ++++ b/auto/MkSrc/Create.pm +@@ -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}; +diff --git a/auto/MkSrc/Info.pm b/auto/MkSrc/Info.pm +index 5d30ec5..a131b2e 100644 +--- a/auto/MkSrc/Info.pm ++++ b/auto/MkSrc/Info.pm +@@ -60,6 +60,7 @@ each proc sub should take the following argv + 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 follows: + 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 +diff --git a/auto/MkSrc/ProcCc.pm b/auto/MkSrc/ProcCc.pm +index 47c4338..98cc435 100644 +--- a/auto/MkSrc/ProcCc.pm ++++ b/auto/MkSrc/ProcCc.pm +@@ -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"; +diff --git a/auto/MkSrc/ProcImpl.pm b/auto/MkSrc/ProcImpl.pm +index b8628fd..3d0f220 100644 +--- a/auto/MkSrc/ProcImpl.pm ++++ b/auto/MkSrc/ProcImpl.pm +@@ -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 ${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; + }; +diff --git a/auto/MkSrc/Read.pm b/auto/MkSrc/Read.pm +index 4b3d1d0..4bf640e 100644 +--- a/auto/MkSrc/Read.pm ++++ b/auto/MkSrc/Read.pm +@@ -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/(? "%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 + { +diff --git a/common/convert.cpp b/common/convert.cpp +index 7fd3895..77804c0 100644 +--- a/common/convert.cpp ++++ b/common/convert.cpp +@@ -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 + struct DecodeDirect : public Decode + { ++ DecodeDirect() {type_width = sizeof(Chr);} + void decode(const char * in0, int size, FilterCharVector & out) const { + const Chr * in = reinterpret_cast(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(in0 +size); ++ const Chr * stop = reinterpret_cast(in0) + size/sizeof(Chr); + for (;in != stop; ++in) +- out.append(*in); ++ out.append(*in, sizeof(Chr)); + } + } + PosibErr decode_ec(const char * in0, int size, +@@ -535,6 +542,7 @@ namespace acommon { + template + 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 + 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(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 unsupported_null_term_wide_string_err_(const char * func) { ++ static bool reported_to_stderr = false; ++ PosibErr 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(); ++ } ++ + } +diff --git a/common/convert.hpp b/common/convert.hpp +index 76332ee..c948973 100644 +--- a/common/convert.hpp ++++ b/common/convert.hpp +@@ -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(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 unsupported_null_term_wide_string_err_(const char * func); ++ void unsupported_null_term_wide_string_abort_(const char * func); ++ ++ static inline PosibErr 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 +diff --git a/common/document_checker.cpp b/common/document_checker.cpp +index 5e510c4..0ccf1cd 100644 +--- a/common/document_checker.cpp ++++ b/common/document_checker.cpp +@@ -44,7 +44,9 @@ namespace acommon { + void DocumentChecker::process(const char * str, int size) + { + proc_str_.clear(); +- conv_->decode(str, size, proc_str_); ++ PosibErr 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(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; +diff --git a/common/document_checker.hpp b/common/document_checker.hpp +index d35bb88..11a3c73 100644 +--- a/common/document_checker.hpp ++++ b/common/document_checker.hpp +@@ -36,6 +36,7 @@ namespace acommon { + PosibErr 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_;} +diff --git a/configure.ac b/configure.ac +index ed26945..51a31cb 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -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, +diff --git a/manual/aspell.texi b/manual/aspell.texi +index 080f894..f331fb0 100644 +--- a/manual/aspell.texi ++++ b/manual/aspell.texi +@@ -158,7 +158,8 @@ Installing + + * Generic Install Instructions:: + * HTML Manuals and "make clean":: +-* Curses Notes:: ++* Curses Notes:: ++* Upgrading from Aspell 0.60.7:: + * Loadable Filter Notes:: + * Upgrading from Aspell 0.50:: + * Upgrading from Aspell .33/Pspell .12:: +@@ -2196,18 +2197,26 @@ int correct = aspell_speller_check(spell_checker, @var{word}, @var{size}); + @end smallexample + + @noindent +-@var{word} is expected to be a @code{const char *} character +-string. If the encoding is set to be @code{ucs-2} or +-@code{ucs-4} @var{word} is expected to be a cast +-from either @code{const u16int *} or @code{const u32int *} +-respectively. @code{u16int} and @code{u32int} are generally +-@code{unsigned short} and @code{unsigned int} respectively. +-@var{size} is the length of the string or @code{-1} if the string +-is null terminated. If the string is a cast from @code{const u16int +-*} or @code{const u32int *} then @code{@i{size}} is the amount of +-space in bytes the string takes up after being cast to @code{const +-char *} and not the true size of the string. @code{sspell_speller_check} +-will return @code{0} if it is not found and non-zero otherwise. ++@var{word} is expected to be a @code{const char *} character string. ++@var{size} is the length of the string or @code{-1} if the string is ++null terminated. @code{aspell_speller_check} will return @code{0} if it is not found ++and non-zero otherwise. ++ ++If you are using the @code{ucs-2} or @code{ucs-4} encoding then the ++string is expected to be either a 2 or 4 byte wide integer ++(respectively) and the @code{_w} macro vesion should be used: ++ ++@smallexample ++int correct = aspell_speller_check_w(spell_checker, @var{word}, @var{size}); ++@end smallexample ++ ++The macro will cast the string to to the correct type and convert ++@var{size} into bytes for you and then a call the special wide version of the ++function that will make sure the encoding is correct for the type ++passed in. For compatibility with older versions of Aspell the normal ++non-wide functions can still be used provided that the size of the ++string, in bytes, is also passed in. Null terminated @code{ucs-2} or ++@code{ucs-4} are no longer supported when using the non-wide functions. + + If the word is not correct, then the @code{suggest} method can be used + to come up with likely replacements. +@@ -2226,7 +2235,28 @@ delete_aspell_string_enumeration(elements); + + Notice how @code{elements} is deleted but @code{suggestions} is not. + The value returned by @code{suggestions} is only valid to the next +-call to @code{suggest}. Once a replacement is made the ++call to @code{suggest}. ++ ++If you are using the @code{ucs-2} or @code{ucs-4} encoding then, in ++addition to using the @code{_w} macro for the @code{suggest} method, you ++should also use the @code{_w} macro with the @code{next} method which ++will cast the string to the correct type for you. For example, if you ++are using the @code{ucs-2} encoding and the string is a @code{const ++uint16_t *} then you should use: ++ ++@smallexample ++AspellWordList * suggestions = aspell_speller_suggest_w(spell_checker, ++ @var{word}, @var{size}); ++AspellStringEnumeration * elements = aspell_word_list_elements(suggestions); ++const uint16_t * word; ++while ( (word = aspell_string_enumeration_next_w(uint16_t, aspell_elements)) != NULL ) ++@{ ++ // add to suggestion list ++@} ++delete_aspell_string_enumeration(elements); ++@end smallexample ++ ++Once a replacement is made the + @code{store_repl} method should be used to communicate the replacement + pair back to the spell checker (for the reason, @pxref{Notes on + Storing Replacement Pairs}). Its usage is as follows: +diff --git a/manual/readme.texi b/manual/readme.texi +index 4bfb2e2..ae680da 100644 +--- a/manual/readme.texi ++++ b/manual/readme.texi +@@ -15,14 +15,16 @@ The latest version can always be found at GNU Aspell's home page at + @uref{http://aspell.net}. + + @menu +-* Generic Install Instructions:: +-* HTML Manuals and "make clean":: +-* Curses Notes:: +-* Loadable Filter Notes:: +-* Upgrading from Aspell 0.50:: +-* Upgrading from Aspell .33/Pspell .12:: +-* Upgrading from a Pre-0.50 snapshot:: +-* WIN32 Notes:: ++* Generic Install Instructions:: ++* HTML Manuals and "make clean":: ++* Curses Notes:: ++* Upgrading from Aspell 0.60.7:: ++* Loadable Filter Notes:: ++* Using 32-Bit Dictionaries on a 64-Bit System:: ++* Upgrading from Aspell 0.50:: ++* Upgrading from Aspell .33/Pspell .12:: ++* Upgrading from a Pre-0.50 snapshot:: ++* WIN32 Notes:: + @end menu + + @node Generic Install Instructions +@@ -120,6 +122,52 @@ In addition your system must also support the @code{mblen} function. + Although this function was defined in the ISO C89 standard (ANSI + X3.159-1989), not all systems have it. + ++@node Upgrading from Aspell 0.60.7 ++@appendixsec Upgrading from Aspell 0.60.7 ++ ++To prevent a potentially unbounded buffer over-read, Aspell no longer ++supports null-terminated UCS-2 and UCS-4 encoded strings with the ++original C API. Null-termianted 8-bit or UTF-8 encoded strings are ++still supported, as are UCS-2 and UCS-4 encoded strings when the ++length is passed in. ++ ++As of Aspell 0.60.8 a function from the original API that expects an ++encoded string as a parameter will return meaningless results (or an ++error code) if string is null terminated and the encoding is set to ++@code{ucs-2} or @code{ucs-4}. In addition, a single: ++@example ++ERROR: aspell_speller_check: Null-terminated wide-character strings unsupported when used this way. ++@end example ++will be printed to standard error the first time one of those ++functions is called. ++ ++Application that use null-terminated UCS-2/4 strings should either (1) ++use the interface intended for working with wide-characters ++(@xref{Through the C API}); or (2) define ++@code{ASPELL_ENCODE_SETTING_SECURE} before including @code{aspell.h}. ++In the latter case is is important that the application explicitly ++sets the encoding to a known value. Defining ++@code{ASPELL_ENCODE_SETTING_SECURE} and not setting the encoding ++explicitly or allowing user of the application to set the encoding ++could result in an unbounded buffer over-read. ++ ++If it is necessary to preserve binary compatibility with older ++versions of Aspell, the easiest thing would be to determine the length ++of the UCS-2/4 string---in bytes---and pass that in. Due to an ++implemenation detail, existing API functions can be made to work with ++null-terminated UCS-2/4 strings safely by passing in either @code{-2} ++or @code{-4} (corresponding to the width of the character type) as the ++size. Doing so, however, will cause a buffer over-read for unpatched ++version of Aspell. To avoid this it will be necessary to parse the ++version string to determine the correct value to use. However, no ++official support will be provided for the latter method. ++ ++If the application can not be recompiled, then Aspell can be configured ++to preserve the old behavior by passing ++@option{--enable-sloppy-null-term-strings} to @command{configure}. When Aspell ++is compiled this way the version string will include the string ++@samp{ SLOPPY}. ++ + @node Loadable Filter Notes + @appendixsec Loadable Filter Notes + +@@ -129,8 +177,7 @@ errors when trying to use a filter, then it is likely that loadable + filter support is not working yet on your platform. Thus, in order to + get Aspell to work correctly you will need to avoid compiling the + filters as individual modules by using the +-@option{--enable-compile-in-filters} when configuring Aspell with +-@command{./configure}. ++@option{--enable-compile-in-filters} @command{configure} option. + + @node Upgrading from Aspell 0.50 + @appendixsec Upgrading from Aspell 0.50 +diff --git a/test/cxx_warnings_test.cpp b/test/cxx_warnings_test.cpp +new file mode 100644 +index 0000000..923bfc8 +--- /dev/null ++++ b/test/cxx_warnings_test.cpp +@@ -0,0 +1,84 @@ ++ #include ++#include ++#include ++#include ++ ++#include ++ ++const uint16_t test_word[] = {'c','a','f', 0x00E9, 0}; ++const uint16_t test_incorrect[] = {'c','a','f', 'e', 0}; ++const uint16_t test_doc[] = {'T', 'h', 'e', ' ', 'c','a','f', 0x00E9, '.', 0}; ++ ++int fail = 0; ++ ++void f1() { ++ AspellConfig * spell_config = new_aspell_config(); ++ aspell_config_replace(spell_config, "master", "en_US-w_accents"); ++ aspell_config_replace(spell_config, "encoding", "ucs-2"); ++ AspellCanHaveError * possible_err = new_aspell_speller(spell_config); ++ AspellSpeller * spell_checker = 0; ++ if (aspell_error_number(possible_err) != 0) { ++ fprintf(stderr, "%s", aspell_error_message(possible_err)); ++ exit(0); ++ } else { ++ spell_checker = to_aspell_speller(possible_err); ++ } ++ int correct = aspell_speller_check_w(spell_checker, test_word, -1); ++ if (!correct) { ++ fprintf(stderr, "%s", "fail: expected word to be correct\n"); ++ fail = 1; ++ } ++ correct = aspell_speller_check_w(spell_checker, test_incorrect, -1); ++ if (correct) { ++ fprintf(stderr, "%s", "fail: expected word to be incorrect\n"); ++ fail = 1; ++ } ++ const AspellWordList * suggestions = aspell_speller_suggest_w(spell_checker, test_incorrect, -1); ++ AspellStringEnumeration * elements = aspell_word_list_elements(suggestions); ++ const uint16_t * word = aspell_string_enumeration_next_w(uint16_t, elements); ++ if (memcmp(word, test_word, sizeof(test_incorrect)) != 0) { ++ fprintf(stderr, "%s", "fail: first suggesion is not what is expected\n"); ++ fail = 1; ++ delete_aspell_string_enumeration(elements); ++ } ++ if (fail) ++ printf("not ok\n"); ++ else ++ printf("ok\n"); ++} ++ ++void f2() { ++ AspellConfig * spell_config = new_aspell_config(); ++ aspell_config_replace(spell_config, "master", "en_US-w_accents"); ++ aspell_config_replace(spell_config, "encoding", "ucs-2"); ++ AspellCanHaveError * possible_err = new_aspell_speller(spell_config); ++ AspellSpeller * spell_checker = 0; ++ if (aspell_error_number(possible_err) != 0) { ++ fprintf(stderr, "%s", aspell_error_message(possible_err)); ++ exit(0); ++ } else { ++ spell_checker = to_aspell_speller(possible_err); ++ } ++ int correct = aspell_speller_check_w(spell_checker, test_word, -1); ++ if (!correct) { ++ fprintf(stderr, "%s", "fail: expected word to be correct\n"); ++ fail = 1; ++ } ++ correct = aspell_speller_check_w(spell_checker, test_incorrect, -1); ++ if (correct) { ++ fprintf(stderr, "%s", "fail: expected word to be incorrect\n"); ++ fail = 1; ++ } ++ const AspellWordList * suggestions = aspell_speller_suggest_w(spell_checker, test_incorrect, -1); ++ AspellStringEnumeration * elements = aspell_word_list_elements(suggestions); ++ const uint16_t * word = aspell_string_enumeration_next_w(uint16_t, elements); ++ if (memcmp(word, test_word, sizeof(test_incorrect)) != 0) { ++ fprintf(stderr, "%s", "fail: first suggesion is not what is expected\n"); ++ fail = 1; ++ delete_aspell_string_enumeration(elements); ++ } ++ if (fail) ++ printf("not ok\n"); ++ else ++ printf("ok\n"); ++} +diff --git a/test/wide_test_invalid.c b/test/wide_test_invalid.c +new file mode 100644 +index 0000000..d5e2ed7 +--- /dev/null ++++ b/test/wide_test_invalid.c +@@ -0,0 +1,69 @@ ++#include ++#include ++#include ++#include ++ ++#include ++ ++const uint16_t test_word[] = {'c','a','f', 0x00E9, 0}; ++const uint16_t test_incorrect[] = {'c','a','f', 'e', 0}; ++const uint16_t test_doc[] = {'T', 'h', 'e', ' ', 'c','a','f', 'e', '.', 0}; ++ ++int fail = 0; ++ ++int main() { ++ AspellConfig * spell_config = new_aspell_config(); ++ aspell_config_replace(spell_config, "master", "en_US-w_accents"); ++ aspell_config_replace(spell_config, "encoding", "ucs-2"); ++ AspellCanHaveError * possible_err = new_aspell_speller(spell_config); ++ AspellSpeller * spell_checker = 0; ++ if (aspell_error_number(possible_err) != 0) { ++ fprintf(stderr, "%s", aspell_error_message(possible_err)); ++ return 2; ++ } else { ++ spell_checker = to_aspell_speller(possible_err); ++ } ++ int correct = aspell_speller_check(spell_checker, (const char *)test_word, -1); ++ if (!correct) { ++ fprintf(stderr, "%s", "fail: expected word to be correct\n"); ++ fail = 1; ++ } ++ correct = aspell_speller_check(spell_checker, (const char *)test_incorrect, -1); ++ if (correct) { ++ fprintf(stderr, "%s", "fail: expected word to be incorrect\n"); ++ fail = 1; ++ } ++ const AspellWordList * suggestions = aspell_speller_suggest(spell_checker, (const char *)test_incorrect, -1); ++ AspellStringEnumeration * elements = aspell_word_list_elements(suggestions); ++ const char * word = aspell_string_enumeration_next(elements); ++ if (memcmp(word, test_word, sizeof(test_incorrect)) != 0) { ++ fprintf(stderr, "%s", "fail: first suggesion is not what is expected\n"); ++ fail = 1; ++ } ++ delete_aspell_string_enumeration(elements); ++ ++ possible_err = new_aspell_document_checker(spell_checker); ++ if (aspell_error(possible_err) != 0) { ++ fprintf(stderr, "Error: %s\n",aspell_error_message(possible_err)); ++ return 2; ++ } ++ AspellDocumentChecker * checker = to_aspell_document_checker(possible_err); ++ aspell_document_checker_process(checker, (const char *)test_doc, -1); ++ ++ AspellToken token = aspell_document_checker_next_misspelling(checker); ++ if (sizeof(test_incorrect) - sizeof(uint16_t) != token.len) { ++ fprintf(stderr, "fail: size of first misspelling (%d) is not what is expected (%lu)\n", ++ token.len, sizeof(test_incorrect) - sizeof(uint16_t)); ++ fail = 1; ++ } else if (memcmp(test_incorrect, (const char *)test_doc + token.offset, token.len) != 0) { ++ fprintf(stderr, "%s", "fail: first misspelling is not what is expected\n"); ++ fail = 1; ++ } ++ if (fail) { ++ printf("not ok\n"); ++ return 1; ++ } else { ++ printf("ok\n"); ++ return 0; ++ } ++} +diff --git a/test/wide_test_valid.c b/test/wide_test_valid.c +new file mode 100644 +index 0000000..bc3006d +--- /dev/null ++++ b/test/wide_test_valid.c +@@ -0,0 +1,69 @@ ++#include ++#include ++#include ++#include ++ ++#include ++ ++const uint16_t test_word[] = {'c','a','f', 0x00E9, 0}; ++const uint16_t test_incorrect[] = {'c','a','f', 'e', 0}; ++const uint16_t test_doc[] = {'T', 'h', 'e', ' ', 'c','a','f', 'e', '.', 0}; ++ ++int fail = 0; ++ ++int main() { ++ AspellConfig * spell_config = new_aspell_config(); ++ aspell_config_replace(spell_config, "master", "en_US-w_accents"); ++ aspell_config_replace(spell_config, "encoding", "ucs-2"); ++ AspellCanHaveError * possible_err = new_aspell_speller(spell_config); ++ AspellSpeller * spell_checker = 0; ++ if (aspell_error_number(possible_err) != 0) { ++ fprintf(stderr, "%s", aspell_error_message(possible_err)); ++ return 2; ++ } else { ++ spell_checker = to_aspell_speller(possible_err); ++ } ++ int correct = aspell_speller_check_w(spell_checker, test_word, -1); ++ if (!correct) { ++ fprintf(stderr, "%s", "fail: expected word to be correct\n"); ++ fail = 1; ++ } ++ correct = aspell_speller_check_w(spell_checker, test_incorrect, -1); ++ if (correct) { ++ fprintf(stderr, "%s", "fail: expected word to be incorrect\n"); ++ fail = 1; ++ } ++ const AspellWordList * suggestions = aspell_speller_suggest_w(spell_checker, test_incorrect, -1); ++ AspellStringEnumeration * elements = aspell_word_list_elements(suggestions); ++ const uint16_t * word = aspell_string_enumeration_next_w(uint16_t, elements); ++ if (memcmp(word, test_word, sizeof(test_incorrect)) != 0) { ++ fprintf(stderr, "%s", "fail: first suggesion is not what is expected\n"); ++ fail = 1; ++ } ++ delete_aspell_string_enumeration(elements); ++ ++ possible_err = new_aspell_document_checker(spell_checker); ++ if (aspell_error(possible_err) != 0) { ++ fprintf(stderr, "Error: %s\n",aspell_error_message(possible_err)); ++ return 2; ++ } ++ AspellDocumentChecker * checker = to_aspell_document_checker(possible_err); ++ aspell_document_checker_process_w(checker, test_doc, -1); ++ ++ AspellToken token = aspell_document_checker_next_misspelling_w(uint16_t, checker); ++ if (4 != token.len) { ++ fprintf(stderr, "fail: size of first misspelling (%d) is not what is expected (%d)\n", ++ token.len, 4); ++ fail = 1; ++ } else if (memcmp(test_incorrect, test_doc + token.offset, token.len) != 0) { ++ fprintf(stderr, "%s", "fail: first misspelling is not what is expected\n"); ++ fail = 1; ++ } ++ if (fail) { ++ printf("not ok\n"); ++ return 1; ++ } else { ++ printf("ok\n"); ++ return 0; ++ } ++} +-- +2.27.0 + diff --git a/CVE-2019-20433-2.patch b/CVE-2019-20433-2.patch new file mode 100644 index 0000000000000000000000000000000000000000..6d0ee610492e5711058ff6038b913ed60afdff70 --- /dev/null +++ b/CVE-2019-20433-2.patch @@ -0,0 +1,56 @@ +From cefd447e5528b08bb0cd6656bc52b4255692cefc Mon Sep 17 00:00:00 2001 +From: Kevin Atkinson +Date: Sat, 17 Aug 2019 20:25:21 -0400 +Subject: [PATCH] Increment library version to reflect API changes. + +--- + Makefile.am | 24 +++++++++++++++++------- + 1 file changed, 17 insertions(+), 7 deletions(-) + +diff --git a/Makefile.am b/Makefile.am +index 950319d..3bbadb7 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -93,10 +93,24 @@ libaspell_la_SOURCES =\ + + libaspell_la_LIBADD = $(LTLIBINTL) $(PTHREAD_LIB) + ++## The version string is current[:revision[:age]] ++## ++## Before a release that has changed the source code at all ++## increment revision. ++## ++## After merging changes that have changed the API in a backwards ++## comptable way set revision to 0 and bump both current and age. ++## ++## Do not change the API in a backwards incompatible way. ++## ++## See "Libtool: Updating version info" ++## (https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html) ++## for more into ++## + if INCREMENTED_SONAME +-libaspell_la_LDFLAGS = -version-info 16:5:0 -no-undefined ++libaspell_la_LDFLAGS = -version-info 19:0:3 -no-undefined + else +-libaspell_la_LDFLAGS = -version-info 16:5:1 -no-undefined ++libaspell_la_LDFLAGS = -version-info 18:0:3 -no-undefined + endif + + if PSPELL_COMPATIBILITY +@@ -104,11 +118,7 @@ libpspell_la_SOURCES = lib/dummy.cpp + + libpspell_la_LIBADD = libaspell.la + +-if INCREMENTED_SONAME +-libpspell_la_LDFLAGS = -version-info 16:5:0 -no-undefined +-else +-libpspell_la_LDFLAGS = -version-info 16:5:1 -no-undefined +-endif ++libpspell_la_LDFLAGS = $(libaspell_la_LDFLAGS) + + endif + +-- +2.27.0 + diff --git a/CVE-2019-25051.patch b/CVE-2019-25051.patch new file mode 100644 index 0000000000000000000000000000000000000000..2f15d380ec0b1c62943fad17cc8ca58ce86578e7 --- /dev/null +++ b/CVE-2019-25051.patch @@ -0,0 +1,96 @@ +From 0718b375425aad8e54e1150313b862e4c6fd324a Mon Sep 17 00:00:00 2001 +From: Kevin Atkinson +Date: Sat, 21 Dec 2019 20:32:47 +0000 +Subject: [PATCH] objstack: assert that the alloc size will fit within a chunk + to prevent a buffer overflow + +Bug found using OSS-Fuze. +--- + common/objstack.hpp | 18 ++++++++++++++---- + 1 file changed, 14 insertions(+), 4 deletions(-) + +diff --git a/common/objstack.hpp b/common/objstack.hpp +index 3997bf7..bd97ccd 100644 +--- a/common/objstack.hpp ++++ b/common/objstack.hpp +@@ -5,6 +5,7 @@ + #include "parm_string.hpp" + #include + #include ++#include + + namespace acommon { + +@@ -26,6 +27,12 @@ class ObjStack + byte * temp_end; + void setup_chunk(); + void new_chunk(); ++ bool will_overflow(size_t sz) const { ++ return offsetof(Node,data) + sz > chunk_size; ++ } ++ void check_size(size_t sz) { ++ assert(!will_overflow(sz)); ++ } + + ObjStack(const ObjStack &); + void operator=(const ObjStack &); +@@ -56,7 +63,7 @@ class ObjStack + void * alloc_bottom(size_t size) { + byte * tmp = bottom; + bottom += size; +- if (bottom > top) {new_chunk(); tmp = bottom; bottom += size;} ++ if (bottom > top) {check_size(size); new_chunk(); tmp = bottom; bottom += size;} + return tmp; + } + // This alloc_bottom will insure that the object is aligned based on the +@@ -66,7 +73,7 @@ class ObjStack + align_bottom(align); + byte * tmp = bottom; + bottom += size; +- if (bottom > top) {new_chunk(); goto loop;} ++ if (bottom > top) {check_size(size); new_chunk(); goto loop;} + return tmp; + } + char * dup_bottom(ParmString str) { +@@ -79,7 +86,7 @@ class ObjStack + // always be aligned as such. + void * alloc_top(size_t size) { + top -= size; +- if (top < bottom) {new_chunk(); top -= size;} ++ if (top < bottom) {check_size(size); new_chunk(); top -= size;} + return top; + } + // This alloc_top will insure that the object is aligned based on +@@ -88,7 +95,7 @@ class ObjStack + {loop: + top -= size; + align_top(align); +- if (top < bottom) {new_chunk(); goto loop;} ++ if (top < bottom) {check_size(size); new_chunk(); goto loop;} + return top; + } + char * dup_top(ParmString str) { +@@ -117,6 +124,7 @@ class ObjStack + void * alloc_temp(size_t size) { + temp_end = bottom + size; + if (temp_end > top) { ++ check_size(size); + new_chunk(); + temp_end = bottom + size; + } +@@ -131,6 +139,7 @@ class ObjStack + } else { + size_t s = temp_end - bottom; + byte * p = bottom; ++ check_size(size); + new_chunk(); + memcpy(bottom, p, s); + temp_end = bottom + size; +@@ -150,6 +159,7 @@ class ObjStack + } else { + size_t s = temp_end - bottom; + byte * p = bottom; ++ check_size(size); + new_chunk(); + memcpy(bottom, p, s); + temp_end = bottom + size; diff --git a/aspell-0.60.7-fileconflict.patch b/aspell-0.60.7-fileconflict.patch new file mode 100644 index 0000000000000000000000000000000000000000..c4b93155f9759fc18c5a082400aa0d3be752f706 --- /dev/null +++ b/aspell-0.60.7-fileconflict.patch @@ -0,0 +1,55 @@ +diff --git a/Makefile.in b/Makefile.in +index f293649..e5d2b1a 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -518,6 +518,7 @@ distcleancheck_listfiles = find . -type f -print + + # These are needed due to a bug in Automake + pkgdatadir = @pkgdatadir@ ++pkgdatadir2 = @pkgdatadir2@ + pkglibdir = @pkglibdir@ + ACLOCAL = @ACLOCAL@ + AMTAR = @AMTAR@ +@@ -2071,7 +2072,7 @@ gen/dirs.h: gen/mk-dirs_h.pl + perl ${srcdir}/gen/mk-dirs_h.pl ${prefix} ${pkgdatadir} ${pkglibdir} ${sysconfdir} > gen/dirs.h + + scripts/run-with-aspell: scripts/run-with-aspell.create +- sh ${srcdir}/scripts/run-with-aspell.create ${pkgdatadir} > scripts/run-with-aspell ++ sh ${srcdir}/scripts/run-with-aspell.create ${pkgdatadir2} > scripts/run-with-aspell + chmod 755 scripts/run-with-aspell + @PSPELL_COMPATIBILITY_TRUE@scripts/pspell-config: scripts/mkconfig + @PSPELL_COMPATIBILITY_TRUE@ sh ${srcdir}/scripts/mkconfig ${VERSION} ${datadir} ${pkgdatadir} +diff --git a/configure b/configure +index 1236c90..8a6e697 100755 +--- a/configure ++++ b/configure +@@ -709,6 +709,7 @@ CXXFLAGS + CXX + pkglibdir + pkgdatadir ++pkgdatadir2 + pkgdocdir + MAINT + MAINTAINER_MODE_FALSE +@@ -3297,18 +3298,21 @@ pkgdatadir=undef + # Check whether --enable-pkgdatadir was given. + if test "${enable_pkgdatadir+set}" = set; then : + enableval=$enable_pkgdatadir; pkgdatadir=$enable_pkgdatadir ++ pkgdatadir2=$enable_pkgdatadir + fi + + + # Check whether --enable-pkgdata-dir was given. + if test "${enable_pkgdata_dir+set}" = set; then : + enableval=$enable_pkgdata_dir; pkgdatadir=$enable_dict_dir ++ pkgdatadir2=$enable_dict_dir + fi + + + if test "$pkgdatadir" = "undef" + then + pkgdatadir=\${libdir}/aspell-0.60 ++ pkgdatadir2=${exec_prefix}/lib/aspell-0.60:${exec_prefix}/lib64/aspell-0.60 + fi + + diff --git a/aspell-0.60.7-mp.patch b/aspell-0.60.7-mp.patch new file mode 100644 index 0000000000000000000000000000000000000000..4f4e94dc23abb1f7be61d55d7fc80899b8fb8aed --- /dev/null +++ b/aspell-0.60.7-mp.patch @@ -0,0 +1,48 @@ +diff --git a/manual/aspell.1 b/manual/aspell.1 +index 854debf..b1106ca 100644 +--- a/manual/aspell.1 ++++ b/manual/aspell.1 +@@ -328,7 +328,6 @@ are also allowed. The \fI/etc/aspell.conf\fR file is a good example of + how to set these options and the Aspell Manual has more detailed info. + .SH SEE ALSO + .PP +-.BR aspell\-import (1), + .BR prezip\-bin (1), + .BR run\-with\-aspell (1), + .BR word\-list\-compress (1) +diff --git a/manual/prezip-bin.1 b/manual/prezip-bin.1 +index afb6c05..09b5784 100644 +--- a/manual/prezip-bin.1 ++++ b/manual/prezip-bin.1 +@@ -99,7 +99,6 @@ the output file is not complete. + .SH SEE ALSO + .PP + .BR aspell (1), +-.BR aspell\-import (1), + .BR run\-with\-aspell (1), + .BR word\-list\-compress (1) + .PP +diff --git a/manual/run-with-aspell.1 b/manual/run-with-aspell.1 +index 8dea131..67f3117 100644 +--- a/manual/run-with-aspell.1 ++++ b/manual/run-with-aspell.1 +@@ -28,7 +28,6 @@ such as ispell's own scripts. + .SH SEE ALSO + .PP + .BR aspell (1), +-.BR aspell\-import (1), + .BR word\-list\-compress (1) + .PP + Aspell is fully documented in its Texinfo manual. See the +diff --git a/manual/word-list-compress.1 b/manual/word-list-compress.1 +index 5126cd2..6686997 100644 +--- a/manual/word-list-compress.1 ++++ b/manual/word-list-compress.1 +@@ -80,7 +80,6 @@ be written to. + .SH SEE ALSO + .PP + .BR aspell (1), +-.BR aspell\-import (1), + .BR prezip\-bin (1), + .BR run\-with\-aspell (1) + .PP diff --git a/aspell-0.60.7-pspell_conf.patch b/aspell-0.60.7-pspell_conf.patch new file mode 100644 index 0000000000000000000000000000000000000000..a5fe8e4a4539f4da0f8229ead0ed72de1bd1e539 --- /dev/null +++ b/aspell-0.60.7-pspell_conf.patch @@ -0,0 +1,65 @@ +diff --git a/Makefile.in b/Makefile.in +index e5d2b1a..bc53e34 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -1019,6 +1019,8 @@ clean-filterLTLIBRARIES: + install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ ++ mkdir -p $(DESTDIR)$(libdir)/pkgconfig; \ ++ cp aspell.pc $(DESTDIR)$(libdir)/pkgconfig/aspell.pc; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ +diff --git a/aspell.pc.in b/aspell.pc.in +new file mode 100644 +index 0000000..13da044 +--- /dev/null ++++ b/aspell.pc.in +@@ -0,0 +1,12 @@ ++prefix=@prefix@ ++exec_prefix=@exec_prefix@ ++libdir=@libdir@ ++includedir=@includedir@ ++pkgdatadir=@pkgdatadir@ ++ ++Name: Aspell ++Description: A spelling checker. ++Version: @VERSION@ ++Requires: ++Libs: -L${libdir} -laspell ++Cflags: -I${includedir} +diff --git a/configure b/configure +index 8a6e697..995a3df 100755 +--- a/configure ++++ b/configure +@@ -18732,7 +18732,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + # # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +-ac_config_files="$ac_config_files Makefile gen/Makefile common/Makefile lib/Makefile data/Makefile auto/Makefile modules/Makefile modules/tokenizer/Makefile modules/speller/Makefile modules/speller/default/Makefile interfaces/Makefile interfaces/cc/Makefile scripts/Makefile examples/Makefile prog/Makefile manual/Makefile po/Makefile.in m4/Makefile modules/filter/Makefile myspell/Makefile lib5/Makefile" ++ac_config_files="$ac_config_files Makefile gen/Makefile common/Makefile lib/Makefile data/Makefile auto/Makefile modules/Makefile modules/tokenizer/Makefile modules/speller/Makefile modules/speller/default/Makefile interfaces/Makefile interfaces/cc/Makefile aspell.pc scripts/Makefile examples/Makefile prog/Makefile manual/Makefile po/Makefile.in m4/Makefile modules/filter/Makefile myspell/Makefile lib5/Makefile" + + cat >confcache <<\_ACEOF + # This file is a shell script that caches the results of configure +@@ -19887,6 +19887,7 @@ do + "modules/filter/Makefile") CONFIG_FILES="$CONFIG_FILES modules/filter/Makefile" ;; + "myspell/Makefile") CONFIG_FILES="$CONFIG_FILES myspell/Makefile" ;; + "lib5/Makefile") CONFIG_FILES="$CONFIG_FILES lib5/Makefile" ;; ++ "aspell.pc") CONFIG_FILES="$CONFIG_FILES aspell.pc" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +diff --git a/scripts/mkconfig b/scripts/mkconfig +index 608e3f7..f15f31c 100755 +--- a/scripts/mkconfig ++++ b/scripts/mkconfig +@@ -15,7 +15,7 @@ case \$1 in + echo "$2" + ;; + --pkgdatadir | pkgdatadir) +- echo "$3" ++ pkg-config aspell --variable=pkgdatadir + ;; + *) + echo "usage: pspell-config version|datadir|pkgdatadir" diff --git a/aspell-0.60.8.tar.gz b/aspell-0.60.8.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..7e4b7664c20017f471dd66a7730d2812c0a880d8 Binary files /dev/null and b/aspell-0.60.8.tar.gz differ diff --git a/aspell.spec b/aspell.spec index c4e42fc0b46ae22d192d03b91f3a97362cefb7d3..0fd445e888ee3349516d2b4eb40e45ed8396fec6 100644 --- a/aspell.spec +++ b/aspell.spec @@ -1,51 +1,50 @@ -Name: aspell -Version: 0.60.6.1 -Release: 25 -Summary: Spell checker -Epoch: 12 -License: LGPLv2+ and LGPLv2 and GPLv2+ and BSD -URL: http://aspell.net/ -Source: ftp://ftp.gnu.org/gnu/aspell/aspell-%{version}.tar.gz - -Patch0000: aspell-0.60.3-install_info.patch -Patch0001: aspell-0.60.5-fileconflict.patch -Patch0002: aspell-0.60.5-pspell_conf.patch -Patch0003: aspell-0.60.6-zero.patch -Patch0004: aspell-0.60.6-mp.patch -Patch0005: aspell-0.60.6.1-dump-personal-abort.patch -Patch0006: aspell-0.60.6.1-aarch64.patch -Patch0007: aspell-0.60.6.1-gcc7-fixes.patch -Patch0008: aspell-0.60.6.1-fix-back-on-empty-vector.patch - -BuildRequires: chrpath gettext ncurses-devel pkgconfig perl-interpreter gcc-c++ +Summary: Spell checker +Name: aspell +Version: 0.60.8 +Release: 1 +Epoch: 12 +# LGPLv2+ .. common/gettext.h +# LGPLv2 .. modules/speller/default/phonet.hpp, +# modules/speller/default/phonet.cpp, +# modules/speller/default/affix.cpp +# GPLv2+ .. ltmain.sh, misc/po-filter.c +# BSD .. myspell/munch.c +License: LGPLv2+ and LGPLv2 and GPLv2+ and BSD +URL: http://aspell.net/ +Source: ftp://ftp.gnu.org/gnu/aspell/aspell-%{version}.tar.gz + +BuildRequires: gcc-c++ make chrpath gettext ncurses-devel pkgconfig perl-interpreter + +Patch0: aspell-0.60.7-fileconflict.patch +Patch1: aspell-0.60.7-pspell_conf.patch +Patch2: aspell-0.60.7-mp.patch + + %description -GNU Aspell is a spell checker intended to replace Ispell. -It can be used as a library and spell checker. Its main -feature is that it provides much better suggestions than -other inspectors, including Ispell and Microsoft Word. -It also has many other technical enhancements to Ispell, -such as the use of shared memory to store dictionaries, -and intelligent processing of personal dictionaries when -multiple Aspell processes are opened at one time. +GNU Aspell is a spell checker designed to eventually replace Ispell. It can +either be used as a library or as an independent spell checker. Its main +feature is that it does a much better job of coming up with possible +suggestions than just about any other spell checker out there for the +English language, including Ispell and Microsoft Word. It also has many +other technical enhancements over Ispell such as using shared memory for +dictionaries and intelligently handling personal dictionaries when more +than one Aspell process is open at once. %package devel -Summary: Libraries and header files for Aspell development -Requires: %{name} = %{epoch}:%{version}-%{release} -Requires: pkgconfig +Summary: Libraries and header files for Aspell development +Requires: %{name} = %{epoch}:%{version}-%{release} +Requires: pkgconfig %description devel The aspell-devel package includes libraries and header files needed for Aspell development. -%package help -Summary: Introduce how to use aspell - -%description help -User's Manual for aspell - %prep -%autosetup -n %{name}-%{version} -p1 +%setup -q +%patch0 -p1 -b .fc +%patch1 -p1 -b .mlib +%patch2 -p1 -b .ai iconv -f iso-8859-2 -t utf-8 < manual/aspell.info > manual/aspell.info.aux mv manual/aspell.info.aux manual/aspell.info @@ -58,25 +57,34 @@ chmod 644 examples/aspell-import cp manual/aspell-import.1 examples/aspell-import.1 %install -%makeinstall +%make_install -install -d ${RPM_BUILD_ROOT}%{_libdir}/aspell-0.60 +mkdir -p ${RPM_BUILD_ROOT}%{_libdir}/aspell-0.60 -mv ${RPM_BUILD_ROOT}%{_libdir}/aspell-0.60/{ispell,spell} ${RPM_BUILD_ROOT}%{_bindir} +mv ${RPM_BUILD_ROOT}%{_libdir}/aspell-0.60/ispell ${RPM_BUILD_ROOT}%{_bindir} +mv ${RPM_BUILD_ROOT}%{_libdir}/aspell-0.60/spell ${RPM_BUILD_ROOT}%{_bindir} -for path in nroff-filter.so sgml-filter.so context-filter.so email-filter.so tex-filter.so texinfo-filter.so; -do - chrpath --delete ${RPM_BUILD_ROOT}%{_libdir}/aspell-0.60//$path; -done +chrpath --delete ${RPM_BUILD_ROOT}%{_libdir}/aspell-0.60//nroff-filter.so +chrpath --delete ${RPM_BUILD_ROOT}%{_libdir}/aspell-0.60//sgml-filter.so +chrpath --delete ${RPM_BUILD_ROOT}%{_libdir}/aspell-0.60//context-filter.so +chrpath --delete ${RPM_BUILD_ROOT}%{_libdir}/aspell-0.60//email-filter.so +chrpath --delete ${RPM_BUILD_ROOT}%{_libdir}/aspell-0.60//tex-filter.so +chrpath --delete ${RPM_BUILD_ROOT}%{_libdir}/aspell-0.60//texinfo-filter.so +chrpath --delete ${RPM_BUILD_ROOT}%{_libdir}/aspell-0.60//markdown-filter.so chrpath --delete ${RPM_BUILD_ROOT}%{_bindir}/aspell chrpath --delete ${RPM_BUILD_ROOT}%{_libdir}/libpspell.so.* -rm -rf ${RPM_BUILD_ROOT}%{_mandir}/man1/aspell-import.1 +rm -f ${RPM_BUILD_ROOT}%{_libdir}/libaspell.la +rm -f ${RPM_BUILD_ROOT}%{_libdir}/libpspell.la +rm -f ${RPM_BUILD_ROOT}%{_libdir}/aspell-0.60/*-filter.la +rm -f ${RPM_BUILD_ROOT}%{_bindir}/aspell-import +rm -f ${RPM_BUILD_ROOT}%{_mandir}/man1/aspell-import.1 +rm -f ${RPM_BUILD_ROOT}%{_infodir}/dir %find_lang %{name} %files -f %{name}.lang -%doc COPYING examples/aspell-import examples/aspell-import.1 +%doc README TODO COPYING examples/aspell-import examples/aspell-import.1 %dir %{_libdir}/aspell-0.60 %{_bindir}/a* %{_bindir}/ispell @@ -87,10 +95,10 @@ rm -rf ${RPM_BUILD_ROOT}%{_mandir}/man1/aspell-import.1 %{_libdir}/lib*.so.* %{_libdir}/aspell-0.60/* %{_infodir}/aspell.* -%exclude %{_libdir}/libaspell.la -%exclude %{_libdir}/libpspell.la -%exclude %{_libdir}/aspell-0.60/*-filter.la -%exclude %{_bindir}/aspell-import +%{_mandir}/man1/aspell.1.* +%{_mandir}/man1/run-with-aspell.1* +%{_mandir}/man1/word-list-compress.1* +%{_mandir}/man1/prezip-bin.1.* %files devel %dir %{_includedir}/pspell @@ -100,15 +108,488 @@ rm -rf ${RPM_BUILD_ROOT}%{_mandir}/man1/aspell-import.1 %{_libdir}/lib*spell.so %{_libdir}/pkgconfig/* %{_infodir}/aspell-dev.* - -%files help -%doc README TODO -%{_mandir}/man1/aspell.1.* -%{_mandir}/man1/run-with-aspell.1* -%{_mandir}/man1/word-list-compress.1* -%{_mandir}/man1/prezip-bin.1.* %{_mandir}/man1/pspell-config.1* %changelog -* Wed Nov 27 2019 yangjian - 12:0.60.6.1-25 -- Package init +* Mon Aug 09 2021 Mohan Boddu - 12:0.60.8-8 +- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags + Related: rhbz#1991688 + +* Thu Apr 15 2021 Mohan Boddu - 12:0.60.8-7 +- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937 + +* Tue Jan 26 2021 Fedora Release Engineering - 12:0.60.8-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Mon Jul 27 2020 Fedora Release Engineering - 12:0.60.8-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Tue Jul 14 2020 Tom Stellard - 12:0.60.8-4 +- Use make macros +- https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro + +* Tue Jan 28 2020 Fedora Release Engineering - 12:0.60.8-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Tue Oct 22 2019 Nikola Forró - 12:0.60.8-2 +- remove RPATH from markdown-filter.so + +* Fri Oct 18 2019 Nikola Forró - 12:0.60.8-1 +- resolves: #1761152 + update to 0.60.8 + +* Mon Aug 19 2019 Nikola Forró - 12:0.60.7-1 +- resolves: #1742373 + update to 0.60.7 + +* Wed Jul 24 2019 Fedora Release Engineering - 12:0.60.6.1-26 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Thu Jan 31 2019 Fedora Release Engineering - 12:0.60.6.1-25 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Thu Jul 12 2018 Fedora Release Engineering - 12:0.60.6.1-24 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Thu Jun 28 2018 Nikola Forró - 12:0.60.6.1-23 +- remove ldconfig from scriptlets + +* Tue Jun 19 2018 Nikola Forró - 12:0.60.6.1-22 +- remove install-info from scriptlets + +* Wed Apr 04 2018 Nikola Forró - 12:0.60.6.1-21 +- resolves: #1562364 + do not call back() on an empty vector + +* Tue Feb 20 2018 Nikola Forró - 12:0.60.6.1-20 +- add missing gcc-c++ build dependency + +* Wed Feb 07 2018 Fedora Release Engineering - 12:0.60.6.1-19 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Wed Aug 02 2017 Fedora Release Engineering - 12:0.60.6.1-18 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering - 12:0.60.6.1-17 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Thu Feb 23 2017 Nikola Forró - 12:0.60.6.1-16 +- resolves: #1423239 + fix building with GCC 7 + +* Fri Feb 10 2017 Fedora Release Engineering - 12:0.60.6.1-15 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Tue Dec 06 2016 Nikola Forró - 12:0.60.6.1-14 +- resolves: #1401713 + add perl to BuildRequires + +* Wed Feb 03 2016 Fedora Release Engineering - 12:0.60.6.1-13 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Wed Jun 17 2015 Fedora Release Engineering - 12:0.60.6.1-12 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Sat May 02 2015 Kalev Lember - 12:0.60.6.1-11 +- Rebuilt for GCC 5 C++11 ABI change + +* Fri Aug 15 2014 Fedora Release Engineering - 12:0.60.6.1-10 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Sat Jun 07 2014 Fedora Release Engineering - 12:0.60.6.1-9 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Sat Aug 03 2013 Fedora Release Engineering - 12:0.60.6.1-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Mon Mar 25 2013 Peter Schiffer - 12:0.60.6.1-7 +- resolves: #925034 + add support for aarch64 + +* Wed Feb 13 2013 Fedora Release Engineering - 12:0.60.6.1-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Mon Aug 27 2012 Peter Schiffer - 12:0.60.6.1-5 +- done some minor .spec file cleanup + +* Thu Jul 19 2012 Peter Schiffer - 12:0.60.6.1-4 +- resolves: #813261 + fixed crash when trying to run "aspell dump personal" + +* Wed Jul 18 2012 Fedora Release Engineering - 12:0.60.6.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Thu Jan 12 2012 Fedora Release Engineering - 12:0.60.6.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Tue Aug 16 2011 Peter Schiffer - 12:0.60.6.1-1 +- resolves: #718946 + update to 0.60.6.1 + +* Mon May 2 2011 Ivana Hutarova Varekova - 12.0.60.6-15 +- fix minor problems in spec file + +* Mon Feb 07 2011 Fedora Release Engineering - 12:0.60.6-14 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Tue Aug 17 2010 Ivana Hutarova Varekova - 12.0.60.6-13 +- remove obsolete links from man-pages + +* Tue Mar 2 2010 Ivana Hutarova Varekova - 12.0.60.6-12 +- fix -devel scriptlets + +* Tue Dec 15 2009 Ivana Hutarova Varekova - 12:0.60.6-11 +- remove obsolete patch + +* Fri Dec 4 2009 Ivana Hutarova Varekova - 12:0.60.6-10 +- fix rpath problem (chrpath) + +* Tue Dec 1 2009 Ivana Hutarova Varekova - 12:0.60.6-9 +- add --disable-rpath to configure part + remove remanent obsolete tags + fix license field + +* Fri Nov 27 2009 Ivana Hutarova Varekova - 12:0.60.6-8 +- change summary name + remove outdated Obsoletes, Conflicts and Provides flag + fix requirement to install-info (pre -> post) + move aspell-import to documentation part + remove exit 0 from scriptlets + +* Mon Aug 10 2009 Ivana Varekova - 12:0.60.6-7 +- fix installation with --excludedocs option (#515911) + +* Fri Jul 24 2009 Fedora Release Engineering - 12:0.60.6-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Mon Feb 23 2009 Fedora Release Engineering - 12:0.60.6-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Thu Feb 12 2009 Ivana Varekova - 12:0.60.6-4 +- remove aspell-en require + +* Mon Sep 1 2008 Ivana Varekova - 12:0.60.6-3 +- fix patch format + +* Thu May 29 2008 Ivana Varekova - 12:0.60.6-2 +- Resolves: #447428 + aspell sigserv on checking file with 0 length + +* Wed May 7 2008 Ivana Varekova - 12:0.60.6-1 +- update to 0.60.6 + +* Wed Feb 20 2008 Fedora Release Engineering - 12:0.60.5-5 +- Autorebuild for GCC 4.3 + +* Tue Jan 22 2008 Ivana Varekova - 12:0.60.5-4 +- add gcc43 patch + +* Thu Feb 8 2007 Ivana Varekova - 12:0.60.5-3 +- incorporate package review feedback + +* Mon Jan 22 2007 Ivana Varekova - 12:0.60.5-2 +- Resolves: 223676 + fix non-failsafe install-info problem + +* Tue Jan 2 2007 Ivana Varekova - 12:0.60.5-1 +- update to 0.60.4 +- cleanup spec file + +* Wed Nov 8 2006 Ivana Varekova - 12:0.60.4-1 +- update to 0.60.4 + +* Wed Jul 12 2006 Jesse Keating - 12:0.60.3-7.1 +- rebuild + +* Tue May 23 2006 Ivana Varekova - 12:0.60.3-7 +- fix multilib problem (used pkgconfig) + +* Wed Mar 22 2006 Ivana Varekova - 12:0.60.3-6 +- remove .la files (bug 184184) + +* Thu Mar 2 2006 Ivana Varekova - 12:0.60.3-5 +- update aspell man page (bug 183205) + +* Tue Feb 21 2006 Ivana Varekova - 12:0.60.3-4 +- fix multilib file conflict + +* Fri Feb 10 2006 Jesse Keating - 12:0.60.3-3.2 +- bump again for double-long bug on ppc(64) + +* Tue Feb 07 2006 Jesse Keating - 12:0.60.3-3.1 +- rebuilt for new gcc4.1 snapshot and glibc changes + +* Mon Dec 19 2005 Ivana Varekova 12:0.60.3-3 +- fix for gcc 4.1 + +* Fri Dec 09 2005 Jesse Keating +- rebuilt + +* Fri Jul 15 2005 Ivana Varekova 12:0.60.3-2 +- fix install-info problem + +* Wed Jul 13 2005 Ivana Varekova 12:0.60.3-1 +- update to 0.60.3 - (bug 141968) thanks to Dawid Gajownik +- add BuildRequires: ncurses-devel, gettext +- add config script patch (thanks tmraz@redhat.com) + + +* Mon Mar 7 2005 Ivana Varekova 12:0.50.5-6 +- rebuilt + +* Thu Jan 13 2005 Adrian Havill 12:0.50.5-5 +- added aspell-pt_BR to the obsoletes + +* Fri Nov 12 2004 Warren Togami 12:0.50.5-4 +- rebuild + +* Wed Oct 06 2004 Than Ngo 12:0.50.5-3.fc3 +- add obsolete aspell-config + +* Mon Aug 23 2004 Adrian Havill 12:0.50.5-2.fc3 +- fix doc dir (#128140) (don't flag aspell doc stuff with the doc macro + flag due to rpm badness) + +* Mon Jun 21 2004 Warren Togami 12:0.50.5-1 +- update to 0.50.5 + +* Tue Jun 15 2004 Elliot Lee +- rebuilt + +* Tue Mar 02 2004 Elliot Lee +- rebuilt + +* Fri Feb 13 2004 Elliot Lee +- rebuilt + +* Thu Jan 29 2004 Adrian Havill 12:0.50.50.3-18 +- make rpm own some unclaimed dirs (#112984, #113778) +- explicitly claim kbd anbd dat files in /usr/share/aspell +- a little spec file files cleanup-- macro subs, dir prefix +- make /usr/lib/aspell; don't make the dictionary packages do it + +* Mon Nov 17 2003 Thomas Woerner 12:0.50.3-17 +- fixed build: added make to %%build to avoid rpath for build directory + +* Tue Oct 07 2003 Adrian Havill 12:0.50.3-16 +- moved spell compat script from /usr/share/aspell to /usr/bin (#105921) + +* Tue Jul 01 2003 Adrian Havill 11:0.50.3-15 +- moved ispell compat script from /usr/share/aspell to /usr/bin (#90907) + +* Tue Jun 24 2003 Adrian Havill 10:0.50.3-14 +- removed emacs/xemacs el files which are already provided + +* Wed Jun 18 2003 Adrian Havill 9:0.50.3-13 +- provide pspell-devel in addition to obsoleting it + +* Tue Jun 10 2003 Adrian Havill 8:0.50.3-12 +- obsolete old dicts designed for previous aspell + +* Wed Jun 04 2003 Elliot Lee +- rebuilt + +* Fri May 30 2003 Joe Orton 7:0.50.3-10 +- rebuild again to fix libpspell deps + +* Fri May 30 2003 Joe Orton 7:0.50.3-9 +- remove ExcludeArch + +* Thu May 22 2003 Jeremy Katz 7:0.50.3-8 +- fix build with gcc 3.3 + +* Wed May 21 2003 Adrian Havill 0.50.3-7 +- require aspell-en for upgrades + +* Sun May 11 2003 Jeremy Katz 6:0.50.3-6 +- -devel should obsolete pspell-devel + +* Tue May 6 2003 Joe Orton 0.50.3-5 +- include libpspell.so in devel package + +* Thu May 1 2003 Adrian Havill 0.50.3-4 +- removed .la files + +* Wed Apr 16 2003 Adrian Havill 0.50.3-3 +- Changed the header for provides, obsoletes, epoch +- fixed config prefix in dirs.h + +* Wed Apr 16 2003 Adrian Havill 0.50.3-1 +- upgrade to 0.50.3 + +* Wed Jan 22 2003 Tim Powers +- rebuilt + +* Fri Nov 8 2002 Tim Powers +- fix broken pspell epoch dep +- create $RPM_BUILD_ROOT/usr/bin by hand +- remove /usr/doc +- fix hardcoding of /usr/lib so that we can build on x86_64 + +* Tue Aug 13 2002 Nalin Dahyabhai 0.33.7.1-16 +- require pspell and pspell-devel using the proper epoch + +* Sat Aug 10 2002 Elliot Lee +- rebuilt with gcc-3.2 (we hope) + +* Mon Jul 22 2002 Tim Powers 0.33.7.1-14 +- rebuild using gcc-3.2-0.1 + +* Fri Jun 21 2002 Tim Powers 0.33.7.1-13 +- automated rebuild + +* Thu Jun 13 2002 Trond Eivind Glomsrød 0.33.7.1-12 +- Rebuild to make it work again... #66708 + +* Thu May 23 2002 Tim Powers +- automated rebuild + +* Mon May 13 2002 Trond Eivind Glomsrød 0.33.7.1-10 +- Rebuild + +* Thu Feb 21 2002 Trond Eivind Glomsrød 0.33.7.1-9 +- Disable evil patch + +* Mon Jan 28 2002 Trond Eivind Glomsrød 0.33.7.1-8 +- Build on more archs (doh) + +* Tue Jan 22 2002 Trond Eivind Glomsrød 0.33.7.1-7 +- Make it compile with new compiler (evil workaround) + +* Wed Jan 16 2002 Trond Eivind Glomsrød 0.33.7.1-5 +- Rebuild +- Unexclude alpha + +* Fri Dec 14 2001 Trond Eivind Glomsrød 0.33.7.1-3 +- Rebuild +- Don't build on alpha + +* Mon Oct 29 2001 Bernhard Rosenkraenzer 0.33.7.1-2 +- "make it work with gcc 3.1" ;) + +* Tue Sep 18 2001 Trond Eivind Glomsrød 0.33.7.1-1 +- 0.33.7.1, which is a "make it work with gcc 3" release + +* Wed Sep 12 2001 Tim Powers +- rebuild with new gcc and binutils + +* Thu Aug 9 2001 Trond Eivind Glomsrød 0.33.7-1 +- 0.33.7 bugfix release. Requested by the author, it fixes + coredumps in sug-mode and when not using typo-analyses. + It also contains code cleanups so it compiles with -ansi +- should fix coredump on IA64 (#49746) + +* Wed Jul 11 2001 Trond Eivind Glomsrød +- Add the .la files in the main package - used for dynamic loading + +* Sun Jun 3 2001 Trond Eivind Glomsrød +- 0.33.6.3, which includes the fix made yesterday + +* Sat Jun 2 2001 Trond Eivind Glomsrød +- Make it search for directories in the correct location + +* Wed May 30 2001 Trond Eivind Glomsrød +- No more workarounds at the specfile level + +* Tue May 29 2001 Trond Eivind Glomsrød +- Use custom ltmain.sh to work around buggy bundled libtool + +* Sun May 20 2001 Trond Eivind Glomsrød +- 0.33.6 +- use standard %%configure macro - it works now. + +* Fri May 11 2001 Bernhard Rosenkraenzer 0.33.5-2 +- Rebuild with new libltdl + +* Mon Apr 23 2001 Trond Eivind Glomsrød +- 0.33.5 + +* Thu Nov 30 2000 Trond Eivind Glomsrød +- use new emacs init scheme for Emacs and XEmacs + +* Wed Nov 22 2000 Trond Eivind Glomsrød +- .32.6 + +* Sat Aug 19 2000 Trond Eivind Glomsrød +- .32.5 bugfix release (also contains improved documentation), + obsolete old patch +- the compatibility scripts are now part of the package itself +- clean up build procedure +- remove manual.aux file from docs (#16424) + +* Sun Aug 06 2000 Trond Eivind Glomsrød +- .32.1 bugfix release, obsolete old patch +- rename to 0.32.1 +- add patch from author to change his email address +- add spell and ispell compatibility scripts + +* Fri Aug 04 2000 Trond Eivind Glomsrød +- rebuild + +* Tue Aug 01 2000 Trond Eivind Glomsrød +- remember to obsolete ispell +- build the Canadian and British dictionaries here now, + as part of the main package. Same package names and + descriptions. + +* Mon Jul 24 2000 Trond Eivind Glomsrød +- .32 +- remove old patches, add a patch since namespace isn't + polluted as much anymore (as opposed to older toolchain) + +* Wed Jul 19 2000 Trond Eivind Glomsrød +- rebuild + +* Wed Jul 12 2000 Prospector +- automatic rebuild + +* Tue Jul 4 2000 Jakub Jelinek +- Rebuild with new C++ + +* Fri Jun 30 2000 Trond Eivind Glomsrød +- use RPM_OPT_FLAGS, not just -O0 +- dont include .la-files + +* Fri Jun 23 2000 Trond Eivind Glomsrød +- excludearch ia64 + +* Fri Jun 23 2000 Trond Eivind Glomsrød +- patch to work around compiler bug(?) wrt. inline functions +- use CFLAGS and CXXFLAGS +- set them to -O0 to work around YACB +- copy libtool files for IA64 support + +* Sun Jun 18 2000 Trond Eivind Glomsrød +- update to .31.1. My patch was upstreamed and is no longer needed. +- new patch added so DESTDIR works properly + +* Fri Jun 16 2000 Trond Eivind Glomsrød +- (this entry includes some old ones...) +- update to .31 +- added patch to make it compile with a pickier compiler +- include /usr/share/pspell + +* Mon May 1 2000 Tim Powers +- updated to .30.1 +- used build fixes from Ryan Weaver's 0.30.1-1 package on sourceforge +- updated URL, download/ftp location +- removed redundant define's at top of spec file + +* Thu Jul 8 1999 Tim Powers +- built for Powertools 6.1 +- removed serial macro definitions from spec file to make versioning + consistant with the other packages we ship. +- changed build root path +- general spec file cleanups + +* Tue Mar 2 1999 Ryan Weaver + [aspell-.27.2-2] +- Changes from .27.1 to .27.2 (Mar 1, 1999) +- Fixed a major bug that caused aspell to dump core when used + without any arguments +- Fixed another major bug that caused aspell to do nothing when used + in interactive mode. +- Added an option to exit in Aspell's interactive mode. +- Removed some old documentation files from the distribution. +- Minor changes on to the section on using Aspell with egcs. +- Minor changes to remove -Wall warnings. diff --git a/aspell.yaml b/aspell.yaml new file mode 100644 index 0000000000000000000000000000000000000000..02403aa317cccf93855246ff7578c9dadeb5f0a5 --- /dev/null +++ b/aspell.yaml @@ -0,0 +1,4 @@ +version_control: git +src_repo: https://git.savannah.gnu.org/git/aspell.git +tag_prefix: "rel-" +seperator: "."