!3 fix CVE-2020-26247
From: @zhanghua1831 Reviewed-by: @wang_yue111,@small_leek Signed-off-by: @small_leek
This commit is contained in:
commit
22c5da70ed
65
CVE-2020-26247-pre.patch
Normal file
65
CVE-2020-26247-pre.patch
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
From 74abb4f2e73bb61b17d9f1a0ad717c881943b877 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Aaron Patterson <aaron.patterson@gmail.com>
|
||||||
|
Date: Wed, 26 Feb 2020 13:51:43 -0800
|
||||||
|
Subject: [PATCH] Work around a bug in libxml2
|
||||||
|
|
||||||
|
This commit works around a bug in libxml2 where parsing schemas can
|
||||||
|
result in dangling pointers which can lead to a segv.
|
||||||
|
|
||||||
|
Upstream bug is here: https://gitlab.gnome.org/GNOME/libxml2/issues/148
|
||||||
|
|
||||||
|
Fixes #1985
|
||||||
|
---
|
||||||
|
ext/nokogiri/xml_schema.c | 29 +++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 29 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/ext/nokogiri/xml_schema.c b/ext/nokogiri/xml_schema.c
|
||||||
|
index da2774b..439f721 100644
|
||||||
|
--- a/ext/nokogiri/xml_schema.c
|
||||||
|
+++ b/ext/nokogiri/xml_schema.c
|
||||||
|
@@ -133,6 +133,31 @@ static VALUE read_memory(VALUE klass, VALUE content)
|
||||||
|
return rb_schema;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Schema creation will remove and deallocate "blank" nodes.
|
||||||
|
+ * If those blank nodes have been exposed to Ruby, they could get freed
|
||||||
|
+ * out from under the VALUE pointer. This function checks to see if any of
|
||||||
|
+ * those nodes have been exposed to Ruby, and if so we should raise an exception.
|
||||||
|
+ */
|
||||||
|
+static int has_blank_nodes_p(VALUE cache)
|
||||||
|
+{
|
||||||
|
+ long i;
|
||||||
|
+
|
||||||
|
+ if (NIL_P(cache)) {
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < RARRAY_LEN(cache); i++) {
|
||||||
|
+ xmlNodePtr node;
|
||||||
|
+ VALUE element = rb_ary_entry(cache, i);
|
||||||
|
+ Data_Get_Struct(element, xmlNode, node);
|
||||||
|
+ if (xmlIsBlankNode(node)) {
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* call-seq:
|
||||||
|
* from_document(doc)
|
||||||
|
@@ -152,6 +177,10 @@ static VALUE from_document(VALUE klass, VALUE document)
|
||||||
|
/* In case someone passes us a node. ugh. */
|
||||||
|
doc = doc->doc;
|
||||||
|
|
||||||
|
+ if (has_blank_nodes_p(DOC_NODE_CACHE(doc))) {
|
||||||
|
+ rb_raise(rb_eArgError, "Creating a schema from a document that has blank nodes exposed to Ruby is dangerous");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
ctx = xmlSchemaNewDocParserCtxt(doc);
|
||||||
|
|
||||||
|
errors = rb_ary_new();
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
278
CVE-2020-26247.patch
Normal file
278
CVE-2020-26247.patch
Normal file
@ -0,0 +1,278 @@
|
|||||||
|
From 9c87439d9afa14a365ff13e73adc809cb2c3d97b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mike Dalessio <mike.dalessio@gmail.com>
|
||||||
|
Date: Mon, 23 Nov 2020 00:47:02 -0500
|
||||||
|
Subject: [PATCH] feat: XML::Schema and RelaxNG creation accept optional
|
||||||
|
ParseOptions
|
||||||
|
|
||||||
|
I'm trying out a new pattern, which is that the parsed object carries
|
||||||
|
around the ParseOptions it was created with, which should make some
|
||||||
|
testing a bit easier.
|
||||||
|
|
||||||
|
I'm also not implementing the "config block" pattern in use for
|
||||||
|
Documents, because I think the UX is weird and I'm hoping to change
|
||||||
|
everything to use kwargs in a 2.0 release, anyway.
|
||||||
|
---
|
||||||
|
ext/nokogiri/xml_relax_ng.c | 39 ++++++++++++++++++--------
|
||||||
|
ext/nokogiri/xml_schema.c | 46 +++++++++++++++++++++++--------
|
||||||
|
lib/nokogiri/xml/parse_options.rb | 2 ++
|
||||||
|
lib/nokogiri/xml/relax_ng.rb | 4 +--
|
||||||
|
lib/nokogiri/xml/schema.rb | 10 ++++---
|
||||||
|
5 files changed, 72 insertions(+), 29 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ext/nokogiri/xml_relax_ng.c b/ext/nokogiri/xml_relax_ng.c
|
||||||
|
index e17b11a..f361d27 100644
|
||||||
|
--- a/ext/nokogiri/xml_relax_ng.c
|
||||||
|
+++ b/ext/nokogiri/xml_relax_ng.c
|
||||||
|
@@ -53,16 +53,24 @@ static VALUE validate_document(VALUE self, VALUE document)
|
||||||
|
*
|
||||||
|
* Create a new RelaxNG from the contents of +string+
|
||||||
|
*/
|
||||||
|
-static VALUE read_memory(VALUE klass, VALUE content)
|
||||||
|
+static VALUE read_memory(int argc, VALUE *argv, VALUE klass)
|
||||||
|
{
|
||||||
|
- xmlRelaxNGParserCtxtPtr ctx = xmlRelaxNGNewMemParserCtxt(
|
||||||
|
- (const char *)StringValuePtr(content),
|
||||||
|
- (int)RSTRING_LEN(content)
|
||||||
|
- );
|
||||||
|
+ VALUE content;
|
||||||
|
+ VALUE parse_options;
|
||||||
|
+ xmlRelaxNGParserCtxtPtr ctx;
|
||||||
|
xmlRelaxNGPtr schema;
|
||||||
|
- VALUE errors = rb_ary_new();
|
||||||
|
+ VALUE errors;
|
||||||
|
VALUE rb_schema;
|
||||||
|
+ int scanned_args = 0;
|
||||||
|
+
|
||||||
|
+ scanned_args = rb_scan_args(argc, argv, "11", &content, &parse_options);
|
||||||
|
+ if (scanned_args == 1) {
|
||||||
|
+ parse_options = rb_const_get(rb_const_get(mNokogiriXml, rb_intern("ParseOptions")), rb_intern("DEFAULT_SCHEMA"));
|
||||||
|
+ }
|
||||||
|
|
||||||
|
+ ctx = xmlRelaxNGNewMemParserCtxt((const char *)StringValuePtr(content), (int)RSTRING_LEN(content));
|
||||||
|
+
|
||||||
|
+ errors = rb_ary_new();
|
||||||
|
xmlSetStructuredErrorFunc((void *)errors, Nokogiri_error_array_pusher);
|
||||||
|
|
||||||
|
#ifdef HAVE_XMLRELAXNGSETPARSERSTRUCTUREDERRORS
|
||||||
|
@@ -90,6 +98,7 @@ static VALUE read_memory(VALUE klass, VALUE content)
|
||||||
|
|
||||||
|
rb_schema = Data_Wrap_Struct(klass, 0, dealloc, schema);
|
||||||
|
rb_iv_set(rb_schema, "@errors", errors);
|
||||||
|
+ rb_iv_set(rb_schema, "@parse_options", parse_options);
|
||||||
|
|
||||||
|
return rb_schema;
|
||||||
|
}
|
||||||
|
@@ -100,18 +109,25 @@ static VALUE read_memory(VALUE klass, VALUE content)
|
||||||
|
*
|
||||||
|
* Create a new RelaxNG schema from the Nokogiri::XML::Document +doc+
|
||||||
|
*/
|
||||||
|
-static VALUE from_document(VALUE klass, VALUE document)
|
||||||
|
+static VALUE from_document(int argc, VALUE *argv, VALUE klass)
|
||||||
|
{
|
||||||
|
+ VALUE document;
|
||||||
|
+ VALUE parse_options;
|
||||||
|
xmlDocPtr doc;
|
||||||
|
xmlRelaxNGParserCtxtPtr ctx;
|
||||||
|
xmlRelaxNGPtr schema;
|
||||||
|
VALUE errors;
|
||||||
|
VALUE rb_schema;
|
||||||
|
+ int scanned_args = 0;
|
||||||
|
+
|
||||||
|
+ scanned_args = rb_scan_args(argc, argv, "11", &document, &parse_options);
|
||||||
|
|
||||||
|
Data_Get_Struct(document, xmlDoc, doc);
|
||||||
|
+ doc = doc->doc; /* In case someone passes us a node. ugh. */
|
||||||
|
|
||||||
|
- /* In case someone passes us a node. ugh. */
|
||||||
|
- doc = doc->doc;
|
||||||
|
+ if (scanned_args == 1) {
|
||||||
|
+ parse_options = rb_const_get(rb_const_get(mNokogiriXml, rb_intern("ParseOptions")), rb_intern("DEFAULT_SCHEMA"));
|
||||||
|
+ }
|
||||||
|
|
||||||
|
ctx = xmlRelaxNGNewDocParserCtxt(doc);
|
||||||
|
|
||||||
|
@@ -142,6 +158,7 @@ static VALUE from_document(VALUE klass, VALUE document)
|
||||||
|
|
||||||
|
rb_schema = Data_Wrap_Struct(klass, 0, dealloc, schema);
|
||||||
|
rb_iv_set(rb_schema, "@errors", errors);
|
||||||
|
+ rb_iv_set(rb_schema, "@parse_options", parse_options);
|
||||||
|
|
||||||
|
return rb_schema;
|
||||||
|
}
|
||||||
|
@@ -155,7 +172,7 @@ void init_xml_relax_ng()
|
||||||
|
|
||||||
|
cNokogiriXmlRelaxNG = klass;
|
||||||
|
|
||||||
|
- rb_define_singleton_method(klass, "read_memory", read_memory, 1);
|
||||||
|
- rb_define_singleton_method(klass, "from_document", from_document, 1);
|
||||||
|
+ rb_define_singleton_method(klass, "read_memory", read_memory, -1);
|
||||||
|
+ rb_define_singleton_method(klass, "from_document", from_document, -1);
|
||||||
|
rb_define_private_method(klass, "validate_document", validate_document, 1);
|
||||||
|
}
|
||||||
|
diff --git a/ext/nokogiri/xml_schema.c b/ext/nokogiri/xml_schema.c
|
||||||
|
index 439f721..ea7c3d3 100644
|
||||||
|
--- a/ext/nokogiri/xml_schema.c
|
||||||
|
+++ b/ext/nokogiri/xml_schema.c
|
||||||
|
@@ -93,15 +93,26 @@ static VALUE validate_file(VALUE self, VALUE rb_filename)
|
||||||
|
*
|
||||||
|
* Create a new Schema from the contents of +string+
|
||||||
|
*/
|
||||||
|
-static VALUE read_memory(VALUE klass, VALUE content)
|
||||||
|
+static VALUE read_memory(int argc, VALUE *argv, VALUE klass)
|
||||||
|
{
|
||||||
|
+ VALUE content;
|
||||||
|
+ VALUE parse_options;
|
||||||
|
+ int parse_options_int;
|
||||||
|
+ xmlSchemaParserCtxtPtr ctx;
|
||||||
|
xmlSchemaPtr schema;
|
||||||
|
- xmlSchemaParserCtxtPtr ctx = xmlSchemaNewMemParserCtxt(
|
||||||
|
- (const char *)StringValuePtr(content),
|
||||||
|
- (int)RSTRING_LEN(content)
|
||||||
|
- );
|
||||||
|
+ VALUE errors;
|
||||||
|
VALUE rb_schema;
|
||||||
|
- VALUE errors = rb_ary_new();
|
||||||
|
+ int scanned_args = 0;
|
||||||
|
+
|
||||||
|
+ scanned_args = rb_scan_args(argc, argv, "11", &content, &parse_options);
|
||||||
|
+ if (scanned_args == 1) {
|
||||||
|
+ parse_options = rb_const_get(rb_const_get(mNokogiriXml, rb_intern("ParseOptions")), rb_intern("DEFAULT_SCHEMA"));
|
||||||
|
+ }
|
||||||
|
+ parse_options_int = (int)NUM2INT(rb_funcall(parse_options, rb_intern("to_i"), 0));
|
||||||
|
+
|
||||||
|
+ ctx = xmlSchemaNewMemParserCtxt((const char *)StringValuePtr(content), (int)RSTRING_LEN(content));
|
||||||
|
+
|
||||||
|
+ errors = rb_ary_new();
|
||||||
|
xmlSetStructuredErrorFunc((void *)errors, Nokogiri_error_array_pusher);
|
||||||
|
|
||||||
|
#ifdef HAVE_XMLSCHEMASETPARSERSTRUCTUREDERRORS
|
||||||
|
@@ -109,7 +120,7 @@ static VALUE read_memory(VALUE klass, VALUE content)
|
||||||
|
ctx,
|
||||||
|
Nokogiri_error_array_pusher,
|
||||||
|
(void *)errors
|
||||||
|
- );
|
||||||
|
+ );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
schema = xmlSchemaParse(ctx);
|
||||||
|
@@ -129,6 +140,7 @@ static VALUE read_memory(VALUE klass, VALUE content)
|
||||||
|
|
||||||
|
rb_schema = Data_Wrap_Struct(klass, 0, dealloc, schema);
|
||||||
|
rb_iv_set(rb_schema, "@errors", errors);
|
||||||
|
+ rb_iv_set(rb_schema, "@parse_options", parse_options);
|
||||||
|
|
||||||
|
return rb_schema;
|
||||||
|
}
|
||||||
|
@@ -164,18 +176,27 @@ static int has_blank_nodes_p(VALUE cache)
|
||||||
|
*
|
||||||
|
* Create a new Schema from the Nokogiri::XML::Document +doc+
|
||||||
|
*/
|
||||||
|
-static VALUE from_document(VALUE klass, VALUE document)
|
||||||
|
+static VALUE from_document(int argc, VALUE *argv, VALUE klass)
|
||||||
|
{
|
||||||
|
+ VALUE document;
|
||||||
|
+ VALUE parse_options;
|
||||||
|
+ int parse_options_int;
|
||||||
|
xmlDocPtr doc;
|
||||||
|
xmlSchemaParserCtxtPtr ctx;
|
||||||
|
xmlSchemaPtr schema;
|
||||||
|
VALUE errors;
|
||||||
|
VALUE rb_schema;
|
||||||
|
+ int scanned_args = 0;
|
||||||
|
+
|
||||||
|
+ scanned_args = rb_scan_args(argc, argv, "11", &document, &parse_options);
|
||||||
|
|
||||||
|
Data_Get_Struct(document, xmlDoc, doc);
|
||||||
|
+ doc = doc->doc; /* In case someone passes us a node. ugh. */
|
||||||
|
|
||||||
|
- /* In case someone passes us a node. ugh. */
|
||||||
|
- doc = doc->doc;
|
||||||
|
+ if (scanned_args == 1) {
|
||||||
|
+ parse_options = rb_const_get(rb_const_get(mNokogiriXml, rb_intern("ParseOptions")), rb_intern("DEFAULT_SCHEMA"));
|
||||||
|
+ }
|
||||||
|
+ parse_options_int = (int)NUM2INT(rb_funcall(parse_options, rb_intern("to_i"), 0));
|
||||||
|
|
||||||
|
if (has_blank_nodes_p(DOC_NODE_CACHE(doc))) {
|
||||||
|
rb_raise(rb_eArgError, "Creating a schema from a document that has blank nodes exposed to Ruby is dangerous");
|
||||||
|
@@ -211,6 +232,7 @@ static VALUE from_document(VALUE klass, VALUE document)
|
||||||
|
|
||||||
|
rb_schema = Data_Wrap_Struct(klass, 0, dealloc, schema);
|
||||||
|
rb_iv_set(rb_schema, "@errors", errors);
|
||||||
|
+ rb_iv_set(rb_schema, "@parse_options", parse_options);
|
||||||
|
|
||||||
|
return rb_schema;
|
||||||
|
|
||||||
|
@@ -226,8 +248,8 @@ void init_xml_schema()
|
||||||
|
|
||||||
|
cNokogiriXmlSchema = klass;
|
||||||
|
|
||||||
|
- rb_define_singleton_method(klass, "read_memory", read_memory, 1);
|
||||||
|
- rb_define_singleton_method(klass, "from_document", from_document, 1);
|
||||||
|
+ rb_define_singleton_method(klass, "read_memory", read_memory, -1);
|
||||||
|
+ rb_define_singleton_method(klass, "from_document", from_document, -1);
|
||||||
|
|
||||||
|
rb_define_private_method(klass, "validate_document", validate_document, 1);
|
||||||
|
rb_define_private_method(klass, "validate_file", validate_file, 1);
|
||||||
|
diff --git a/lib/nokogiri/xml/parse_options.rb b/lib/nokogiri/xml/parse_options.rb
|
||||||
|
index 8969578..c6d3d1c 100644
|
||||||
|
--- a/lib/nokogiri/xml/parse_options.rb
|
||||||
|
+++ b/lib/nokogiri/xml/parse_options.rb
|
||||||
|
@@ -72,6 +72,8 @@ module Nokogiri
|
||||||
|
DEFAULT_XML = RECOVER | NONET
|
||||||
|
# the default options used for parsing HTML documents
|
||||||
|
DEFAULT_HTML = RECOVER | NOERROR | NOWARNING | NONET
|
||||||
|
+ # the default options used for parsing XML schemas
|
||||||
|
+ DEFAULT_SCHEMA = NONET
|
||||||
|
|
||||||
|
attr_accessor :options
|
||||||
|
def initialize options = STRICT
|
||||||
|
diff --git a/lib/nokogiri/xml/relax_ng.rb b/lib/nokogiri/xml/relax_ng.rb
|
||||||
|
index 5a645a4..79bc30c 100644
|
||||||
|
--- a/lib/nokogiri/xml/relax_ng.rb
|
||||||
|
+++ b/lib/nokogiri/xml/relax_ng.rb
|
||||||
|
@@ -4,8 +4,8 @@ module Nokogiri
|
||||||
|
###
|
||||||
|
# Create a new Nokogiri::XML::RelaxNG document from +string_or_io+.
|
||||||
|
# See Nokogiri::XML::RelaxNG for an example.
|
||||||
|
- def RelaxNG string_or_io
|
||||||
|
- RelaxNG.new(string_or_io)
|
||||||
|
+ def RelaxNG(string_or_io, options = ParseOptions::DEFAULT_SCHEMA)
|
||||||
|
+ RelaxNG.new(string_or_io, options)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
diff --git a/lib/nokogiri/xml/schema.rb b/lib/nokogiri/xml/schema.rb
|
||||||
|
index 65a7bcd..a88f69c 100644
|
||||||
|
--- a/lib/nokogiri/xml/schema.rb
|
||||||
|
+++ b/lib/nokogiri/xml/schema.rb
|
||||||
|
@@ -4,8 +4,8 @@ module Nokogiri
|
||||||
|
###
|
||||||
|
# Create a new Nokogiri::XML::Schema object using a +string_or_io+
|
||||||
|
# object.
|
||||||
|
- def Schema string_or_io
|
||||||
|
- Schema.new(string_or_io)
|
||||||
|
+ def Schema(string_or_io, options = ParseOptions::DEFAULT_SCHEMA)
|
||||||
|
+ Schema.new(string_or_io, options)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@@ -29,12 +29,14 @@ module Nokogiri
|
||||||
|
class Schema
|
||||||
|
# Errors while parsing the schema file
|
||||||
|
attr_accessor :errors
|
||||||
|
+ # The Nokogiri::XML::ParseOptions used to parse the schema
|
||||||
|
+ attr_accessor :parse_options
|
||||||
|
|
||||||
|
###
|
||||||
|
# Create a new Nokogiri::XML::Schema object using a +string_or_io+
|
||||||
|
# object.
|
||||||
|
- def self.new string_or_io
|
||||||
|
- from_document Nokogiri::XML(string_or_io)
|
||||||
|
+ def self.new string_or_io, options = ParseOptions::DEFAULT_SCHEMA
|
||||||
|
+ from_document(Nokogiri::XML(string_or_io), options)
|
||||||
|
end
|
||||||
|
|
||||||
|
###
|
||||||
|
--
|
||||||
|
2.23.0
|
||||||
|
|
||||||
@ -7,13 +7,15 @@
|
|||||||
Summary: An HTML, XML, SAX, and Reader parser
|
Summary: An HTML, XML, SAX, and Reader parser
|
||||||
Name: rubygem-%{gem_name}
|
Name: rubygem-%{gem_name}
|
||||||
Version: %{mainver}
|
Version: %{mainver}
|
||||||
Release: 1
|
Release: 2
|
||||||
License: MIT
|
License: MIT
|
||||||
URL: https://nokogiri.org
|
URL: https://nokogiri.org
|
||||||
Source0: https://rubygems.org/gems/%{gem_name}-%{mainver}%{?prever}.gem
|
Source0: https://rubygems.org/gems/%{gem_name}-%{mainver}%{?prever}.gem
|
||||||
Source1: https://github.com/sparklemotion/%{gem_name}/archive/v%{mainver}.tar.gz
|
Source1: https://github.com/sparklemotion/%{gem_name}/archive/v%{mainver}.tar.gz
|
||||||
# Shut down libxml2 version unmatching warning
|
# Shut down libxml2 version unmatching warning
|
||||||
Patch0: %{name}-1.6.6.4-shutdown-libxml2-warning.patch
|
Patch0: %{name}-1.6.6.4-shutdown-libxml2-warning.patch
|
||||||
|
Patch1: CVE-2020-26247-pre.patch
|
||||||
|
Patch2: CVE-2020-26247.patch
|
||||||
BuildRequires: ruby(release) ruby(rubygems) rubygem(minitest) rubygems-devel
|
BuildRequires: ruby(release) ruby(rubygems) rubygem(minitest) rubygems-devel
|
||||||
Obsoletes: ruby-%{gem_name} <= 1.5.2-2
|
Obsoletes: ruby-%{gem_name} <= 1.5.2-2
|
||||||
BuildRequires: gcc rubygem(pkg-config) libxml2-devel libxslt-devel ruby-devel
|
BuildRequires: gcc rubygem(pkg-config) libxml2-devel libxslt-devel ruby-devel
|
||||||
@ -53,6 +55,8 @@ pushd tmpunpackdir
|
|||||||
gem unpack %{SOURCE0}
|
gem unpack %{SOURCE0}
|
||||||
cd %{gem_name}-%{version}
|
cd %{gem_name}-%{version}
|
||||||
%patch0 -p1
|
%patch0 -p1
|
||||||
|
%patch1 -p1
|
||||||
|
%patch2 -p1
|
||||||
gem specification -l --ruby %{SOURCE0} > %{gem_name}.gemspec
|
gem specification -l --ruby %{SOURCE0} > %{gem_name}.gemspec
|
||||||
sed -i \
|
sed -i \
|
||||||
-e 's|, "ports/archives/[^"][^"]*"||g' \
|
-e 's|, "ports/archives/[^"][^"]*"||g' \
|
||||||
@ -145,5 +149,8 @@ popd
|
|||||||
%{gem_dir}/doc/%{gem_name}-%{mainver}%{?prever}/
|
%{gem_dir}/doc/%{gem_name}-%{mainver}%{?prever}/
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Wed Mar 17 2021 zhanghua <zhanghua40@huawei.com> - 1.10.5-2
|
||||||
|
- fix CVE-2020-26247
|
||||||
|
|
||||||
* Wed Aug 19 2020 luoshengwei <luoshengwei@huawei.com> - 1.10.5-1
|
* Wed Aug 19 2020 luoshengwei <luoshengwei@huawei.com> - 1.10.5-1
|
||||||
- package init
|
- package init
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user