已开启
fix: CVE-2026-12480 - master #46
hongjinghao创建于 8月3日
fix: CVE-2026-12480 - master #46
已开启
共 2 个文件变更+399-1
| @@ -0,0 +1,391 @@ | |||
| 1 | +From d5a88bdb137c0d3039b8f4bbbe8c7099925cc10c Mon Sep 17 00:00:00 2001 | ||
| 2 | +From: hertschuh <1091026+hertschuh@users.noreply.github.com> | ||
| 3 | +Date: Thu, 30 Apr 2026 15:50:00 -0700 | ||
| 4 | +Subject: [PATCH] Refactor and share H5 validation code between legacy and new | ||
| 5 | + format. (#22801) | ||
| 6 | + | ||
| 7 | + | ||
| 8 | +Conflict: File renamed: keras/src/legacy/saving/legacy_h5_format.py -> keras/saving/legacy/hdf5_format.py; Adapted import paths from keras.src.* to keras.* (2.12.0 layout); Skipped 1 non-critical file (file_editor.py does not exist in 2.12.0); Kept try/except ImportError for h5py (module_utils not in 2.12.0); Dropped _verify_group/_verify_dataset removal and H5IOStore cursor pattern refactoring (methods don't exist in 2.12.0); Adapted H5IOStore.get to use safe_get_h5_group for ExternalLink/SoftLink validation | ||
| 9 | +--- | ||
| 10 | + keras/saving/legacy/hdf5_format.py | 106 ++++++++++++++++++++----------------- | ||
| 11 | + keras/saving/saving_lib.py | 64 +++++++++++++++++++++- | ||
| 12 | + 2 files changed, 119 insertions(+), 51 deletions(-) | ||
| 13 | + | ||
| 14 | +diff --git a/keras/saving/legacy/hdf5_format.py b/keras/saving/legacy/hdf5_format.py | ||
| 15 | +index 8b57d28..da05e42 100644 | ||
| 16 | +--- a/keras/saving/legacy/hdf5_format.py | ||
| 17 | ++++ b/keras/saving/legacy/hdf5_format.py | ||
| 18 | +@@ -27,6 +27,8 @@ from keras.optimizers import optimizer_v1 | ||
| 19 | + from keras.saving.legacy import model_config as model_config_lib | ||
| 20 | + from keras.saving.legacy import saving_utils | ||
| 21 | + from keras.saving.legacy.saved_model import json_utils | ||
| 22 | ++from keras.saving.saving_lib import safe_get_h5_dataset | ||
| 23 | ++from keras.saving.saving_lib import safe_get_h5_group | ||
| 24 | + from keras.utils.generic_utils import LazyLoader | ||
| 25 | + from keras.utils.io_utils import ask_to_proceed_with_overwrite | ||
| 26 | + | ||
| 27 | +@@ -194,7 +196,9 @@ def load_model_from_hdf5(filepath, custom_objects=None, compile=True): | ||
| 28 | + ) | ||
| 29 | + | ||
| 30 | + # set weights | ||
| 31 | +- load_weights_from_hdf5_group(f["model_weights"], model) | ||
| 32 | ++ load_weights_from_hdf5_group( | ||
| 33 | ++ safe_get_h5_group(f, "model_weights"), model | ||
| 34 | ++ ) | ||
| 35 | + | ||
| 36 | + if compile: | ||
| 37 | + # instantiate optimizer | ||
| 38 | +@@ -657,11 +661,11 @@ def _convert_rnn_weights(layer, weights): | ||
| 39 | + return weights | ||
| 40 | + | ||
| 41 | + | ||
| 42 | +-def save_optimizer_weights_to_hdf5_group(hdf5_group, optimizer): | ||
| 43 | ++def save_optimizer_weights_to_hdf5_group(group, optimizer): | ||
| 44 | + """Saves optimizer weights of a optimizer to a HDF5 group. | ||
| 45 | + | ||
| 46 | + Args: | ||
| 47 | +- hdf5_group: HDF5 group. | ||
| 48 | ++ group: HDF5 group. | ||
| 49 | + optimizer: optimizer instance. | ||
| 50 | + """ | ||
| 51 | + if isinstance(optimizer, optimizer_base.Optimizer): | ||
| 52 | +@@ -669,7 +673,7 @@ def save_optimizer_weights_to_hdf5_group(hdf5_group, optimizer): | ||
| 53 | + else: | ||
| 54 | + symbolic_weights = getattr(optimizer, "weights") | ||
| 55 | + if symbolic_weights: | ||
| 56 | +- weights_group = hdf5_group.create_group("optimizer_weights") | ||
| 57 | ++ weights_group = group.create_group("optimizer_weights") | ||
| 58 | + weight_names = [str(w.name).encode("utf8") for w in symbolic_weights] | ||
| 59 | + save_attributes_to_hdf5_group( | ||
| 60 | + weights_group, "weight_names", weight_names | ||
| 61 | +@@ -686,36 +690,37 @@ def save_optimizer_weights_to_hdf5_group(hdf5_group, optimizer): | ||
| 62 | + param_dset[:] = val | ||
| 63 | + | ||
| 64 | + | ||
| 65 | +-def load_optimizer_weights_from_hdf5_group(hdf5_group): | ||
| 66 | ++def load_optimizer_weights_from_hdf5_group(group): | ||
| 67 | + """Load optimizer weights from a HDF5 group. | ||
| 68 | + | ||
| 69 | + Args: | ||
| 70 | +- hdf5_group: A pointer to a HDF5 group. | ||
| 71 | ++ group: HDF5 group. | ||
| 72 | + | ||
| 73 | + Returns: | ||
| 74 | + data: List of optimizer weight names. | ||
| 75 | + """ | ||
| 76 | +- weights_group = hdf5_group["optimizer_weights"] | ||
| 77 | ++ weights_group = safe_get_h5_group(group, "optimizer_weights") | ||
| 78 | + optimizer_weight_names = load_attributes_from_hdf5_group( | ||
| 79 | + weights_group, "weight_names" | ||
| 80 | + ) | ||
| 81 | + return [ | ||
| 82 | +- weights_group[weight_name] for weight_name in optimizer_weight_names | ||
| 83 | ++ safe_get_h5_dataset(weights_group, weight_name) | ||
| 84 | ++ for weight_name in optimizer_weight_names | ||
| 85 | + ] | ||
| 86 | + | ||
| 87 | + | ||
| 88 | +-def save_subset_weights_to_hdf5_group(f, weights): | ||
| 89 | ++def save_subset_weights_to_hdf5_group(group, weights): | ||
| 90 | + """Save top-level weights of a model to a HDF5 group. | ||
| 91 | + | ||
| 92 | + Args: | ||
| 93 | +- f: HDF5 group. | ||
| 94 | ++ group: HDF5 group. | ||
| 95 | + weights: List of weight variables. | ||
| 96 | + """ | ||
| 97 | + weight_values = backend.batch_get_value(weights) | ||
| 98 | + weight_names = [w.name.encode("utf8") for w in weights] | ||
| 99 | +- save_attributes_to_hdf5_group(f, "weight_names", weight_names) | ||
| 100 | ++ save_attributes_to_hdf5_group(group, "weight_names", weight_names) | ||
| 101 | + for name, val in zip(weight_names, weight_values): | ||
| 102 | +- param_dset = f.create_dataset(name, val.shape, dtype=val.dtype) | ||
| 103 | ++ param_dset = group.create_dataset(name, val.shape, dtype=val.dtype) | ||
| 104 | + if not val.shape: | ||
| 105 | + # scalar | ||
| 106 | + param_dset[()] = val | ||
| 107 | +@@ -723,37 +728,37 @@ def save_subset_weights_to_hdf5_group(f, weights): | ||
| 108 | + param_dset[:] = val | ||
| 109 | + | ||
| 110 | + | ||
| 111 | +-def save_weights_to_hdf5_group(f, model): | ||
| 112 | ++def save_weights_to_hdf5_group(group, model): | ||
| 113 | + """Saves the weights of a list of layers to a HDF5 group. | ||
| 114 | + | ||
| 115 | + Args: | ||
| 116 | +- f: HDF5 group. | ||
| 117 | ++ group: HDF5 group. | ||
| 118 | + model: Model instance. | ||
| 119 | + """ | ||
| 120 | + from keras import __version__ as keras_version | ||
| 121 | + | ||
| 122 | + save_attributes_to_hdf5_group( | ||
| 123 | +- f, "layer_names", [layer.name.encode("utf8") for layer in model.layers] | ||
| 124 | ++ group, "layer_names", [layer.name.encode("utf8") for layer in model.layers] | ||
| 125 | + ) | ||
| 126 | +- f.attrs["backend"] = backend.backend().encode("utf8") | ||
| 127 | +- f.attrs["keras_version"] = str(keras_version).encode("utf8") | ||
| 128 | ++ group.attrs["backend"] = backend.backend().encode("utf8") | ||
| 129 | ++ group.attrs["keras_version"] = str(keras_version).encode("utf8") | ||
| 130 | + | ||
| 131 | + # Sort model layers by layer name to ensure that group names are strictly | ||
| 132 | + # growing to avoid prefix issues. | ||
| 133 | + for layer in sorted(model.layers, key=lambda x: x.name): | ||
| 134 | +- g = f.create_group(layer.name) | ||
| 135 | ++ layer_group = group.create_group(layer.name) | ||
| 136 | + weights = _legacy_weights(layer) | ||
| 137 | +- save_subset_weights_to_hdf5_group(g, weights) | ||
| 138 | ++ save_subset_weights_to_hdf5_group(layer_group, weights) | ||
| 139 | + weights = model._trainable_weights + model._non_trainable_weights | ||
| 140 | +- g = f.create_group("top_level_model_weights") | ||
| 141 | +- save_subset_weights_to_hdf5_group(g, weights) | ||
| 142 | ++ layer_group = group.create_group("top_level_model_weights") | ||
| 143 | ++ save_subset_weights_to_hdf5_group(layer_group, weights) | ||
| 144 | + | ||
| 145 | + | ||
| 146 | +-def load_subset_weights_from_hdf5_group(f): | ||
| 147 | ++def load_subset_weights_from_hdf5_group(group): | ||
| 148 | + """Load layer weights of a model from hdf5. | ||
| 149 | + | ||
| 150 | + Args: | ||
| 151 | +- f: A pointer to a HDF5 group. | ||
| 152 | ++ group: HDF5 group. | ||
| 153 | + | ||
| 154 | + Returns: | ||
| 155 | + List of NumPy arrays of the weight values. | ||
| 156 | +@@ -762,29 +767,32 @@ def load_subset_weights_from_hdf5_group(f): | ||
| 157 | + ValueError: in case of mismatch between provided model | ||
| 158 | + and weights file. | ||
| 159 | + """ | ||
| 160 | +- weight_names = load_attributes_from_hdf5_group(f, "weight_names") | ||
| 161 | +- return [np.asarray(f[weight_name]) for weight_name in weight_names] | ||
| 162 | ++ weight_names = load_attributes_from_hdf5_group(group, "weight_names") | ||
| 163 | ++ return [ | ||
| 164 | ++ np.asarray(safe_get_h5_dataset(group, weight_name)) | ||
| 165 | ++ for weight_name in weight_names | ||
| 166 | ++ ] | ||
| 167 | + | ||
| 168 | + | ||
| 169 | +-def load_weights_from_hdf5_group(f, model): | ||
| 170 | ++def load_weights_from_hdf5_group(group, model): | ||
| 171 | + """Implements topological (order-based) weight loading. | ||
| 172 | + | ||
| 173 | + Args: | ||
| 174 | +- f: A pointer to a HDF5 group. | ||
| 175 | ++ group: HDF5 group. | ||
| 176 | + model: Model instance. | ||
| 177 | + | ||
| 178 | + Raises: | ||
| 179 | + ValueError: in case of mismatch between provided layers | ||
| 180 | + and weights file. | ||
| 181 | + """ | ||
| 182 | +- if "keras_version" in f.attrs: | ||
| 183 | +- original_keras_version = f.attrs["keras_version"] | ||
| 184 | ++ if "keras_version" in group.attrs: | ||
| 185 | ++ original_keras_version = group.attrs["keras_version"] | ||
| 186 | + if hasattr(original_keras_version, "decode"): | ||
| 187 | + original_keras_version = original_keras_version.decode("utf8") | ||
| 188 | + else: | ||
| 189 | + original_keras_version = "1" | ||
| 190 | +- if "backend" in f.attrs: | ||
| 191 | +- original_backend = f.attrs["backend"] | ||
| 192 | ++ if "backend" in group.attrs: | ||
| 193 | ++ original_backend = group.attrs["backend"] | ||
| 194 | + if hasattr(original_backend, "decode"): | ||
| 195 | + original_backend = original_backend.decode("utf8") | ||
| 196 | + else: | ||
| 197 | +@@ -796,11 +804,11 @@ def load_weights_from_hdf5_group(f, model): | ||
| 198 | + if weights: | ||
| 199 | + filtered_layers.append(layer) | ||
| 200 | + | ||
| 201 | +- layer_names = load_attributes_from_hdf5_group(f, "layer_names") | ||
| 202 | ++ layer_names = load_attributes_from_hdf5_group(group, "layer_names") | ||
| 203 | + filtered_layer_names = [] | ||
| 204 | + for name in layer_names: | ||
| 205 | +- g = f[name] | ||
| 206 | +- weight_names = load_attributes_from_hdf5_group(g, "weight_names") | ||
| 207 | ++ layer_group = safe_get_h5_group(group, name) | ||
| 208 | ++ weight_names = load_attributes_from_hdf5_group(layer_group, "weight_names") | ||
| 209 | + if weight_names: | ||
| 210 | + filtered_layer_names.append(name) | ||
| 211 | + layer_names = filtered_layer_names | ||
| 212 | +@@ -815,10 +823,10 @@ def load_weights_from_hdf5_group(f, model): | ||
| 213 | + # which provides a speedup in TensorFlow. | ||
| 214 | + weight_value_tuples = [] | ||
| 215 | + for k, name in enumerate(layer_names): | ||
| 216 | +- g = f[name] | ||
| 217 | ++ layer_group = safe_get_h5_group(group, name) | ||
| 218 | + layer = filtered_layers[k] | ||
| 219 | + symbolic_weights = _legacy_weights(layer) | ||
| 220 | +- weight_values = load_subset_weights_from_hdf5_group(g) | ||
| 221 | ++ weight_values = load_subset_weights_from_hdf5_group(layer_group) | ||
| 222 | + weight_values = preprocess_weights_for_loading( | ||
| 223 | + layer, weight_values, original_keras_version, original_backend | ||
| 224 | + ) | ||
| 225 | +@@ -831,12 +839,12 @@ def load_weights_from_hdf5_group(f, model): | ||
| 226 | + ) | ||
| 227 | + weight_value_tuples += zip(symbolic_weights, weight_values) | ||
| 228 | + | ||
| 229 | +- if "top_level_model_weights" in f: | ||
| 230 | ++ if "top_level_model_weights" in group: | ||
| 231 | + symbolic_weights = ( | ||
| 232 | + model._trainable_weights + model._non_trainable_weights | ||
| 233 | + ) | ||
| 234 | + weight_values = load_subset_weights_from_hdf5_group( | ||
| 235 | +- f["top_level_model_weights"] | ||
| 236 | ++ safe_get_h5_group(group, "top_level_model_weights") | ||
| 237 | + ) | ||
| 238 | + if len(weight_values) != len(symbolic_weights): | ||
| 239 | + raise ValueError( | ||
| 240 | +@@ -853,13 +861,13 @@ def load_weights_from_hdf5_group(f, model): | ||
| 241 | + layer.finalize_state() | ||
| 242 | + | ||
| 243 | + | ||
| 244 | +-def load_weights_from_hdf5_group_by_name(f, model, skip_mismatch=False): | ||
| 245 | ++def load_weights_from_hdf5_group_by_name(group, model, skip_mismatch=False): | ||
| 246 | + """Implements name-based weight loading (instead of topological loading). | ||
| 247 | + | ||
| 248 | + Layers that have no matching name are skipped. | ||
| 249 | + | ||
| 250 | + Args: | ||
| 251 | +- f: A pointer to a HDF5 group. | ||
| 252 | ++ group: HDF5 group. | ||
| 253 | + model: Model instance. | ||
| 254 | + skip_mismatch: Boolean, whether to skip loading of layers | ||
| 255 | + where there is a mismatch in the number of weights, | ||
| 256 | +@@ -869,21 +877,21 @@ def load_weights_from_hdf5_group_by_name(f, model, skip_mismatch=False): | ||
| 257 | + ValueError: in case of mismatch between provided layers | ||
| 258 | + and weights file and skip_match=False. | ||
| 259 | + """ | ||
| 260 | +- if "keras_version" in f.attrs: | ||
| 261 | +- original_keras_version = f.attrs["keras_version"] | ||
| 262 | ++ if "keras_version" in group.attrs: | ||
| 263 | ++ original_keras_version = group.attrs["keras_version"] | ||
| 264 | + if hasattr(original_keras_version, "decode"): | ||
| 265 | + original_keras_version = original_keras_version.decode("utf8") | ||
| 266 | + else: | ||
| 267 | + original_keras_version = "1" | ||
| 268 | +- if "backend" in f.attrs: | ||
| 269 | +- original_backend = f.attrs["backend"] | ||
| 270 | ++ if "backend" in group.attrs: | ||
| 271 | ++ original_backend = group.attrs["backend"] | ||
| 272 | + if hasattr(original_backend, "decode"): | ||
| 273 | + original_backend = original_backend.decode("utf8") | ||
| 274 | + else: | ||
| 275 | + original_backend = None | ||
| 276 | + | ||
| 277 | + # New file format. | ||
| 278 | +- layer_names = load_attributes_from_hdf5_group(f, "layer_names") | ||
| 279 | ++ layer_names = load_attributes_from_hdf5_group(group, "layer_names") | ||
| 280 | + | ||
| 281 | + # Reverse index of layer name to list of layers with name. | ||
| 282 | + index = {} | ||
| 283 | +@@ -895,8 +903,8 @@ def load_weights_from_hdf5_group_by_name(f, model, skip_mismatch=False): | ||
| 284 | + # which provides a speedup in TensorFlow. | ||
| 285 | + weight_value_tuples = [] | ||
| 286 | + for k, name in enumerate(layer_names): | ||
| 287 | +- g = f[name] | ||
| 288 | +- weight_values = load_subset_weights_from_hdf5_group(g) | ||
| 289 | ++ layer_group = safe_get_h5_group(group, name) | ||
| 290 | ++ weight_values = load_subset_weights_from_hdf5_group(layer_group) | ||
| 291 | + for layer in index.get(name, []): | ||
| 292 | + symbolic_weights = _legacy_weights(layer) | ||
| 293 | + weight_values = preprocess_weights_for_loading( | ||
| 294 | +@@ -944,12 +952,12 @@ def load_weights_from_hdf5_group_by_name(f, model, skip_mismatch=False): | ||
| 295 | + (symbolic_weights[i], weight_values[i]) | ||
| 296 | + ) | ||
| 297 | + | ||
| 298 | +- if "top_level_model_weights" in f: | ||
| 299 | ++ if "top_level_model_weights" in group: | ||
| 300 | + symbolic_weights = ( | ||
| 301 | + model._trainable_weights + model._non_trainable_weights | ||
| 302 | + ) | ||
| 303 | + weight_values = load_subset_weights_from_hdf5_group( | ||
| 304 | +- f["top_level_model_weights"] | ||
| 305 | ++ safe_get_h5_group(group, "top_level_model_weights") | ||
| 306 | + ) | ||
| 307 | + | ||
| 308 | + if len(weight_values) != len(symbolic_weights): | ||
| 309 | +diff --git a/keras/saving/saving_lib.py b/keras/saving/saving_lib.py | ||
| 310 | +index 9e52ecf..12e3bdc 100644 | ||
| 311 | +--- a/keras/saving/saving_lib.py | ||
| 312 | ++++ b/keras/saving/saving_lib.py | ||
| 313 | +@@ -574,6 +574,64 @@ class DiskIOStore: | ||
| 314 | + tf.io.gfile.rmtree(self.tmp_dir) | ||
| 315 | + | ||
| 316 | + | ||
| 317 | ++def safe_get_h5_group(parent, name): | ||
| 318 | ++ """Retrieve a Group within a given File or Group. | ||
| 319 | ++ | ||
| 320 | ++ Args: | ||
| 321 | ++ parent: the parent h5py.File or h5py.Group. | ||
| 322 | ++ name: the name of the Group to retrieve. | ||
| 323 | ++ | ||
| 324 | ++ Returns: | ||
| 325 | ++ The child h5py.Group. | ||
| 326 | ++ """ | ||
| 327 | ++ # Also handles the case when the group is an empty dict initially. | ||
| 328 | ++ if name not in parent: | ||
| 329 | ++ raise KeyError(name) | ||
| 330 | ++ | ||
| 331 | ++ group_type = parent.get(name, default=None, getclass=True, getlink=True) | ||
| 332 | ++ if group_type in (h5py.ExternalLink, h5py.SoftLink): | ||
| 333 | ++ raise ValueError(f"Not allowed: H5 file with {group_type.__name__}") | ||
| 334 | ++ | ||
| 335 | ++ group = parent[name] | ||
| 336 | ++ if not isinstance(group, h5py.Group): | ||
| 337 | ++ raise ValueError( | ||
| 338 | ++ f"Invalid H5 file, expected Group but received {type(group)}" | ||
| 339 | ++ ) | ||
| 340 | ++ return group | ||
| 341 | ++ | ||
| 342 | ++ | ||
| 343 | ++def safe_get_h5_dataset(group, name): | ||
| 344 | ++ """Retrieve a Dataset within a given Group. | ||
| 345 | ++ | ||
| 346 | ++ Args: | ||
| 347 | ++ group: the parent h5py.Group. | ||
| 348 | ++ name: the name of the Dataset to retrieve. | ||
| 349 | ++ | ||
| 350 | ++ Returns: | ||
| 351 | ++ The child h5py.Dataset. | ||
| 352 | ++ """ | ||
| 353 | ++ # Also handles the case when the group is an empty dict initially. | ||
| 354 | ++ if name not in group: | ||
| 355 | ++ raise KeyError(name) | ||
| 356 | ++ | ||
| 357 | ++ dataset_type = group.get(name, default=None, getclass=True, getlink=True) | ||
| 358 | ++ if dataset_type in (h5py.ExternalLink, h5py.SoftLink): | ||
| 359 | ++ raise ValueError(f"Not allowed: H5 file with {dataset_type.__name__}") | ||
| 360 | ++ | ||
| 361 | ++ dataset = group[name] | ||
| 362 | ++ if not isinstance(dataset, h5py.Dataset): | ||
| 363 | ++ raise ValueError( | ||
| 364 | ++ f"Invalid H5 file, expected Dataset, received {type(dataset)}" | ||
| 365 | ++ ) | ||
| 366 | ++ if dataset.external: | ||
| 367 | ++ raise ValueError( | ||
| 368 | ++ f"Not allowed: H5 file with external Dataset: {dataset.external}" | ||
| 369 | ++ ) | ||
| 370 | ++ if dataset.is_virtual: | ||
| 371 | ++ raise ValueError("Not allowed: H5 file with virtual Dataset") | ||
| 372 | ++ return dataset | ||
| 373 | ++ | ||
| 374 | ++ | ||
| 375 | + class H5IOStore: | ||
| 376 | + def __init__(self, root_path, archive=None, mode="r"): | ||
| 377 | + """Numerical variable store backed by HDF5. | ||
| 378 | +@@ -605,9 +663,11 @@ class H5IOStore: | ||
| 379 | + | ||
| 380 | + def get(self, path): | ||
| 381 | + if not path: | ||
| 382 | +- return self.h5_file["vars"] | ||
| 383 | ++ return safe_get_h5_group(self.h5_file, "vars") | ||
| 384 | + if path in self.h5_file and "vars" in self.h5_file[path]: | ||
| 385 | +- return self.h5_file[path]["vars"] | ||
| 386 | ++ return safe_get_h5_group( | ||
| 387 | ++ safe_get_h5_group(self.h5_file, path), "vars" | ||
| 388 | ++ ) | ||
| 389 | + return {} | ||
| 390 | + | ||
| 391 | + def close(self): | ||
| @@ -1,7 +1,7 @@ | |||
| 1 | %global _empty_manifest_terminate_build 0 | 1 | %global _empty_manifest_terminate_build 0 |
| 2 | Name: python-Keras | 2 | Name: python-Keras |
| 3 | Version: 2.12.0 | 3 | Version: 2.12.0 |
| 4 | -Release: 4 | 4 | +Release: 5 |
| 5 | Summary: Deep Learning for humans | 5 | Summary: Deep Learning for humans |
| 6 | License: Apache-2.0 | 6 | License: Apache-2.0 |
| 7 | URL: https://github.com/keras-team/keras | 7 | URL: https://github.com/keras-team/keras |
| @@ -11,6 +11,7 @@ BuildArch: noarch | |||
| 11 | Patch0: backport-CVE-2025-12058.patch | 11 | Patch0: backport-CVE-2025-12058.patch |
| 12 | Patch1: backport-CVE-2026-12482.patch | 12 | Patch1: backport-CVE-2026-12482.patch |
| 13 | Patch2: backport-CVE-2026-11816.patch | 13 | Patch2: backport-CVE-2026-11816.patch |
| 14 | +Patch6000: backport-CVE-2026-12480.patch | ||
| 14 | 15 | ||
| 15 | Requires: python3-numpy | 16 | Requires: python3-numpy |
| 16 | Requires: python3-scipy | 17 | Requires: python3-scipy |
| @@ -100,6 +101,12 @@ mv %{buildroot}/doclist.lst . | |||
| 100 | %{_docdir}/* | 101 | %{_docdir}/* |
| 101 | 102 | ||
| 102 | %changelog | 103 | %changelog |
| 104 | +* Mon Aug 03 2026 hongjinghao <hongjinghao@huawei.com> - 2.12.0-5 | ||
| 105 | +- Type:CVE | ||
| 106 | +- CVE:CVE-2026-12480 | ||
| 107 | +- SUG:NA | ||
| 108 | +- DESC:fix CVE-2026-12480 | ||
| 109 | + | ||
| 103 | * Wed Jul 22 2026 lizhengde <lizhengde@xfusion.com> - 2.12.0-4 | 110 | * Wed Jul 22 2026 lizhengde <lizhengde@xfusion.com> - 2.12.0-4 |
| 104 | - Type:CVE | 111 | - Type:CVE |
| 105 | - CVE:CVE-2026-11816 | 112 | - CVE:CVE-2026-11816 |