nareshmlx/opencv-pr huggingface dataset:
**File:** doc/tutorials/3d/point_cloud/point_cloud.markdown
**Change Type:** added
**Context:** PR #20471: GSoC module to save and load point cloud

**Code Changes:**
```diff
@@ -0,0 +1,75 @@
+Point cloud visualisation {#tutorial_point_cloud}
+==============================
+
+|    |    |
+| -: | :- |
+| Original author | Dmitrii Klepikov |
+| Compatibility | OpenCV >= 5.0 |
+
+Goal
```

Review comment:
Typo: "possible" and "me" -> "be"
**File:** doc/tutorials/3d/point_cloud/point_cloud.markdown
**Change Type:** added
**Context:** PR #20471: GSoC module to save and load point cloud

**Code Changes:**
```diff
@@ -0,0 +1,75 @@
+Point cloud visualisation {#tutorial_point_cloud}
+==============================
+
+|    |    |
+| -: | :- |
+| Original author | Dmitrii Klepikov |
+| Compatibility | OpenCV >= 5.0 |
+
+Goal
```

Review comment:
It'll be great to add reference to format definition document, if any for all supported mesh types.
**File:** modules/3d/include/opencv2/3d.hpp
**Change Type:** modified
**Context:** PR #20471: GSoC module to save and load point cloud

**Code Changes:**
```diff
@@ -2588,6 +2588,60 @@ class CV_EXPORTS Octree {
     Ptr<Impl> p;
 };
 
+
+/** @brief Loads a point cloud from a file.
+*
+* The function loads point cloud from the specified file and returns it.
+* If the cloud cannot be read, throws an error
+*
```

Review comment:
Add reference to formats description here.
**File:** modules/3d/test/test_pointcloud.cpp
**Change Type:** added
**Context:** PR #20471: GSoC module to save and load point cloud

**Code Changes:**
```diff
@@ -0,0 +1,186 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+
+#include <opencv2/core.hpp>
+#include <vector>
+#include <cstdio>
+
+#include "test_precomp.hpp"
```

Review comment:
the word "_tests" is redundant in test names. I propose to remove it everywhere here.
**File:** doc/tutorials/3d/point_cloud/point_cloud.markdown
**Change Type:** added
**Context:** PR #20471: GSoC module to save and load point cloud

**Code Changes:**
```diff
@@ -0,0 +1,75 @@
+Point cloud visualisation {#tutorial_point_cloud}
+==============================
+
+|    |    |
+| -: | :- |
+| Original author | Dmitrii Klepikov |
+| Compatibility | OpenCV >= 5.0 |
+
+Goal
```

Review comment:
please use "`cv::loadPointCloud`" syntax for function names. Doxygen automatically insert cross links to reference manual for them.
**File:** modules/3d/include/opencv2/3d.hpp
**Change Type:** modified
**Context:** PR #20471: GSoC module to save and load point cloud

**Code Changes:**
```diff
@@ -2588,6 +2588,60 @@ class CV_EXPORTS Octree {
     Ptr<Impl> p;
 };
 
+
+/** @brief Loads a point cloud from a file.
+*
+* The function loads point cloud from the specified file and returns it.
+* If the cloud cannot be read, throws an error
+*
```

Review comment:
Why not markdown on doxygen link?
**File:** modules/3d/test/test_pointcloud.cpp
**Change Type:** added
**Context:** PR #20471: GSoC module to save and load point cloud

**Code Changes:**
```diff
@@ -0,0 +1,186 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+
+#include <opencv2/core.hpp>
+#include <vector>
+#include <cstdio>
+
+#include "test_precomp.hpp"
```

Review comment:
`EXPECT_TRUE(normals.empty())` No need to create empty vector.
**File:** modules/3d/include/opencv2/3d.hpp
**Change Type:** modified
**Context:** PR #20471: GSoC module to save and load point cloud

**Code Changes:**
```diff
@@ -2588,6 +2588,60 @@ class CV_EXPORTS Octree {
     Ptr<Impl> p;
 };
 
+
+/** @brief Loads a point cloud from a file.
+*
+* The function loads point cloud from the specified file and returns it.
+* If the cloud cannot be read, throws an error
+*
```

Review comment:
> OutputArray normals Does all point cloud formats have normals?
**File:** modules/3d/src/pointcloud/load_point_cloud.cpp
**Change Type:** added
**Context:** PR #20471: GSoC module to save and load point cloud
**Review Line:** 18

**Code Changes:**
```diff
+
+#include <memory>
+
+namespace cv {
+
+#if OPENCV_HAVE_FILESYSTEM_SUPPORT
+
+static PointCloudDecoder findDecoder(const String &filename)
+{
+    auto file_ext = getExtension(filename);
+    if (file_ext == "obj" || file_ext == "OBJ")
```

Review comment:
Not sure why we have that condition here. See also: https://github.com/opencv/opencv/issues/15675
**File:** samples/python/point_cloud.py
**Change Type:** added
**Context:** PR #20471: GSoC module to save and load point cloud

**Code Changes:**
```diff
@@ -0,0 +1,23 @@
+import numpy as np
+import cv2 as cv
+
+vertices, _ = cv.loadPointCloud("../data/teapot.obj")
+vertices = np.squeeze(vertices, axis=1)
+print(vertices)
+
+color = [1.0, 1.0, 0.0]
+colors = np.tile(color, (vertices.shape[0], 1))
```

Review comment:
`import cv2 as cv`
**File:** modules/dnn/src/onnx/onnx_importer.cpp
**Change Type:** modified
**Context:** PR #21608: DNN: add depth2space and space2depth layer for onnx importer

**Code Changes:**
```diff
@@ -175,6 +175,7 @@ class ONNXImporter
     void parseSoftMax              (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
     void parseDetectionOutput      (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
     void parseCumSum               (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
+    void parseDepthToSpace         (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
     void parseSimpleLayers         (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
 
     // Domain: com.microsoft
@@ -3183,6 +3184,85 @@ void ONNXImporter::parseCumSum(LayerParams& layerParams, const opencv_onnx::Node
     addLayer(layerParams, node_proto);
```

Review comment:
```cpp std::string modeType = layerParams.get<std::string>("mode", "DCR"); ```
**File:** modules/dnn/src/onnx/onnx_importer.cpp
**Change Type:** modified
**Context:** PR #21608: DNN: add depth2space and space2depth layer for onnx importer

**Code Changes:**
```diff
@@ -175,6 +175,7 @@ class ONNXImporter
     void parseSoftMax              (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
     void parseDetectionOutput      (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
     void parseCumSum               (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
+    void parseDepthToSpace         (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
     void parseSimpleLayers         (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
 
     // Domain: com.microsoft
@@ -3183,6 +3184,85 @@ void ONNXImporter::parseCumSum(LayerParams& layerParams, const opencv_onnx::Node
     addLayer(layerParams, node_proto);
```

Review comment:
```cpp CV_Assert(layerParams.has("blocksize")); int blocksize = layerParams.get<int>("blocksize"); ```
**File:** modules/dnn/src/onnx/onnx_importer.cpp
**Change Type:** modified
**Context:** PR #21608: DNN: add depth2space and space2depth layer for onnx importer

**Code Changes:**
```diff
@@ -175,6 +175,7 @@ class ONNXImporter
     void parseSoftMax              (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
     void parseDetectionOutput      (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
     void parseCumSum               (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
+    void parseDepthToSpace         (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
     void parseSimpleLayers         (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
 
     // Domain: com.microsoft
@@ -3183,6 +3184,85 @@ void ONNXImporter::parseCumSum(LayerParams& layerParams, const opencv_onnx::Node
     addLayer(layerParams, node_proto);
```

Review comment:
I'm not a fan of inpShape[i], you could name each dimension(N, C, H, W), if you want. But it's fine as is.
**File:** modules/dnn/src/onnx/onnx_importer.cpp
**Change Type:** modified
**Context:** PR #21608: DNN: add depth2space and space2depth layer for onnx importer

**Code Changes:**
```diff
@@ -175,6 +175,7 @@ class ONNXImporter
     void parseSoftMax              (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
     void parseDetectionOutput      (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
     void parseCumSum               (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
+    void parseDepthToSpace         (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
     void parseSimpleLayers         (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
 
     // Domain: com.microsoft
@@ -3183,6 +3184,85 @@ void ONNXImporter::parseCumSum(LayerParams& layerParams, const opencv_onnx::Node
     addLayer(layerParams, node_proto);
```

Review comment:
```cpp std::array<int, 6> shape0, perm; std::array<int, 4> shape1; ```
**File:** modules/dnn/src/onnx/onnx_importer.cpp
**Change Type:** modified
**Context:** PR #21608: DNN: add depth2space and space2depth layer for onnx importer

**Code Changes:**
```diff
@@ -175,6 +175,7 @@ class ONNXImporter
     void parseSoftMax              (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
     void parseDetectionOutput      (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
     void parseCumSum               (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
+    void parseDepthToSpace         (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
     void parseSimpleLayers         (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
 
     // Domain: com.microsoft
@@ -3183,6 +3184,85 @@ void ONNXImporter::parseCumSum(LayerParams& layerParams, const opencv_onnx::Node
     addLayer(layerParams, node_proto);
```

Review comment:
We should swap the order of these lines, otherwise it might be UB.
**File:** modules/dnn/src/onnx/onnx_importer.cpp
**Change Type:** modified
**Context:** PR #21608: DNN: add depth2space and space2depth layer for onnx importer
**Review Line:** 3214

**Code Changes:**
```diff
+
+    if (layer_type == "DepthToSpace")
+    {
+        if (modeType == "DCR")
+        {
+            shape0 = {N, blocksize, blocksize, C/(blocksize * blocksize), H, W};
+            perm = {0, 3, 4, 1, 5, 2};
+            shape1 = {N, C/(blocksize * blocksize), H * blocksize, W * blocksize};
+        }
+        else if (modeType == "CRD")
+        {
```

Review comment:
`blockSize` is assumed to be non-zero. Need to validate that (validate inputs).
**File:** modules/dnn/src/onnx/onnx_importer.cpp
**Change Type:** modified
**Context:** PR #21608: DNN: add depth2space and space2depth layer for onnx importer

**Code Changes:**
```diff
@@ -175,6 +175,7 @@ class ONNXImporter
     void parseSoftMax              (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
     void parseDetectionOutput      (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
     void parseCumSum               (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
+    void parseDepthToSpace         (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
     void parseSimpleLayers         (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
 
     // Domain: com.microsoft
@@ -3183,6 +3184,85 @@ void ONNXImporter::parseCumSum(LayerParams& layerParams, const opencv_onnx::Node
     addLayer(layerParams, node_proto);
```

Review comment:
coding style - `else` from new line
**File:** modules/dnn/src/onnx/onnx_importer.cpp
**Change Type:** modified
**Context:** PR #21608: DNN: add depth2space and space2depth layer for onnx importer

**Code Changes:**
```diff
@@ -175,6 +175,7 @@ class ONNXImporter
     void parseSoftMax              (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
     void parseDetectionOutput      (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
     void parseCumSum               (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
+    void parseDepthToSpace         (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
     void parseSimpleLayers         (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
 
     // Domain: com.microsoft
@@ -3183,6 +3184,85 @@ void ONNXImporter::parseCumSum(LayerParams& layerParams, const opencv_onnx::Node
     addLayer(layerParams, node_proto);
```

Review comment:
coding style - keep space after `if`
**File:** modules/dnn/src/onnx/onnx_importer.cpp
**Change Type:** modified
**Context:** PR #21608: DNN: add depth2space and space2depth layer for onnx importer

**Code Changes:**
```diff
@@ -175,6 +175,7 @@ class ONNXImporter
     void parseSoftMax              (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
     void parseDetectionOutput      (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
     void parseCumSum               (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
+    void parseDepthToSpace         (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
     void parseSimpleLayers         (LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto);
 
     // Domain: com.microsoft
@@ -3183,6 +3184,85 @@ void ONNXImporter::parseCumSum(LayerParams& layerParams, const opencv_onnx::Node
     addLayer(layerParams, node_proto);
```

Review comment:
> layerParams.type = layer_type; Is it used anywhere? Below its value is rewritten.
**File:** modules/core/include/opencv2/core/hal/intrin_rvv.hpp
**Change Type:** modified
**Context:** PR #21351: Update universal intrinsics of RVV back-end.
**Review Line:** 561

**Code Changes:**
```diff
+    uchar get0() const
+    {
+        return vmv_x(*pval);
+    }
+    inline v_uint8x16& operator=(const v_uint8x16& vec) {
+        *pval = *(vec.pval);
+        return *this;
+    }
+    inline v_uint8x16(const v_uint8x16& vec) {
+        *pval = *(vec.pval);
+    }
```

Review comment:
It's potential memory leak. pval is already initialized with malloc, see code below.
**File:** modules/core/include/opencv2/core/hal/intrin_rvv.hpp
**Change Type:** modified
**Context:** PR #21351: Update universal intrinsics of RVV back-end.

**Code Changes:**
```diff
@@ -230,6 +230,7 @@ inline vint16mf2_t vwcvt_x_x_v_i16mf2 (vint8mf4_t src, size_t vl)
 
 //////////// Types ////////////
 
+#ifndef __clang__
 struct v_uint8x16
 {
     typedef uchar lane_type;
@@ -531,7 +532,358 @@ struct v_float64x2
     double val[2];
```

Review comment:
It's bad idea. The vector registers are usually local variables in function or several functions in call chain. Each vector variable creation cases expensive call and potentially heap fragmentation. I propose to use vuint8m1_t[nlanes*8] for the field as soon as it's always allocated/
**File:** .github/workflows/timvx_backend_tests.yml
**Change Type:** modified
**Context:** PR #21905: Fixed url for a fork (4.x branch)
**Review Line:** 41

**Code Changes:**
```diff
@@ -37,7 +38,7 @@ jobs:
           cd opencv
           git config user.email "opencv.ci"
           git config user.name "opencv.ci"
-          git pull -v "https://github.com/${{ env.PR_AUTHOR }}/opencv" "${{ env.SOURCE_BRANCH_NAME }}" --allow-unrelated-histories
+          git pull -v "https://github.com/${{ env.PR_AUTHOR_FORK }}" "${{ env.SOURCE_BRANCH_NAME }}"
       - name: configure
         run: |
           cmake -B build -DWITH_TIMVX=ON -DCMAKE_INSTALL_PREFIX=./install -DBUILD_SHARED_LIBS=ON -DBUILD_PERF_TESTS=ON -DBUILD_TESTS=ON -DBUILD_EXAMPLES=OFF -DBUILD_DOCS=OFF -DWITH_OPENCL=OFF opencv
@@ -50,10 +51,6 @@ jobs:
       group: khadas-vim3
```

Review comment:
Is this change made for those who have opencv fork but with repo name changed?
**File:** .github/workflows/timvx_backend_tests.yml
**Change Type:** modified
**Context:** PR #21905: Fixed url for a fork (4.x branch)
**Review Line:** 41

**Code Changes:**
```diff
@@ -37,7 +38,7 @@ jobs:
           cd opencv
           git config user.email "opencv.ci"
           git config user.name "opencv.ci"
-          git pull -v "https://github.com/${{ env.PR_AUTHOR }}/opencv" "${{ env.SOURCE_BRANCH_NAME }}" --allow-unrelated-histories
+          git pull -v "https://github.com/${{ env.PR_AUTHOR_FORK }}" "${{ env.SOURCE_BRANCH_NAME }}"
       - name: configure
         run: |
           cmake -B build -DWITH_TIMVX=ON -DCMAKE_INSTALL_PREFIX=./install -DBUILD_SHARED_LIBS=ON -DBUILD_PERF_TESTS=ON -DBUILD_TESTS=ON -DBUILD_EXAMPLES=OFF -DBUILD_DOCS=OFF -DWITH_OPENCL=OFF opencv
@@ -50,10 +51,6 @@ jobs:
       group: khadas-vim3
```

Review comment:
Yes, we've already met this issue recently ([pipeline](https://github.com/opencv/opencv/runs/6064424452?check_suite_focus=true#step:6:11))
**File:** .github/workflows/timvx_backend_tests.yml
**Change Type:** modified
**Context:** PR #21905: Fixed url for a fork (4.x branch)
**Review Line:** 41

**Code Changes:**
```diff
@@ -37,7 +38,7 @@ jobs:
           cd opencv
           git config user.email "opencv.ci"
           git config user.name "opencv.ci"
-          git pull -v "https://github.com/${{ env.PR_AUTHOR }}/opencv" "${{ env.SOURCE_BRANCH_NAME }}" --allow-unrelated-histories
+          git pull -v "https://github.com/${{ env.PR_AUTHOR_FORK }}" "${{ env.SOURCE_BRANCH_NAME }}"
       - name: configure
         run: |
           cmake -B build -DWITH_TIMVX=ON -DCMAKE_INSTALL_PREFIX=./install -DBUILD_SHARED_LIBS=ON -DBUILD_PERF_TESTS=ON -DBUILD_TESTS=ON -DBUILD_EXAMPLES=OFF -DBUILD_DOCS=OFF -DWITH_OPENCL=OFF opencv
@@ -50,10 +51,6 @@ jobs:
       group: khadas-vim3
```

Review comment:
Okay, I will forward this change to my PR of workflow for ARM64 as well.
**File:** modules/core/src/parallel.cpp
**Change Type:** modified
**Context:** PR #21943: Fix compilation with non glibc.

**Code Changes:**
```diff
@@ -942,7 +942,7 @@ int getNumberOfCPUs_()
 
 #endif
 
-#if !defined(_WIN32) && !defined(__APPLE__)
+#if !defined(_WIN32) && !defined(__APPLE__) && defined(_SC_NPROCESSORS_ONLN)
 
     static unsigned cpu_count_sysconf = (unsigned)sysconf( _SC_NPROCESSORS_ONLN );
     ncpus = minNonZero(ncpus, cpu_count_sysconf);
```

Review comment:
m.b. `&& defined(_SC_NPROCESSORS_ONLN) ?
**File:** modules/core/src/parallel.cpp
**Change Type:** modified
**Context:** PR #21943: Fix compilation with non glibc.

**Code Changes:**
```diff
@@ -942,7 +942,7 @@ int getNumberOfCPUs_()
 
 #endif
 
-#if !defined(_WIN32) && !defined(__APPLE__)
+#if !defined(_WIN32) && !defined(__APPLE__) && defined(_SC_NPROCESSORS_ONLN)
 
     static unsigned cpu_count_sysconf = (unsigned)sysconf( _SC_NPROCESSORS_ONLN );
     ncpus = minNonZero(ncpus, cpu_count_sysconf);
```

Review comment:
right, that is much cleaner, thx !
**File:** .github/workflows/PR-3.4-W10.yaml
**Change Type:** added
**Context:** PR #21888: Added workflow for Github Actions to build and test OpenCV on Windows for 3.4 branch
**Review Line:** 20

**Code Changes:**
```diff
+  GTEST_FILTER_STRING: '-Samples.findFile:ExposureCompensate.SimilarityThreshold:DNNTestNetwork.MobileNet_SSD_v2_TensorFlow*:DNNTestNetwork.Inception_v2_SSD_TensorFlow*:Test_TensorFlow_nets.Inception_v2_SSD*:Test_Darknet_nets.YOLOv4_tiny*:videoio/videocapture_acceleration.read/61:Drawing.ttf_text'
+  GIT_CACHE: c:\Slave\git_cache
+
+jobs:
+  BuildAndTest:
+    runs-on: opencv-cn-win
+    defaults:
+      run:
+        shell: cmd
+    steps:
+    - name: PR info
```

Review comment:
Is this going to be the machine on my side?
**File:** modules/calib3d/src/fisheye.cpp
**Change Type:** modified
**Context:** PR #21834: Add termination criteria to cv::fisheye::undistortPoints()

**Code Changes:**
```diff
@@ -318,7 +318,8 @@ void cv::fisheye::distortPoints(InputArray undistorted, OutputArray distorted, I
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
 /// cv::fisheye::undistortPoints
 
-void cv::fisheye::undistortPoints( InputArray distorted, OutputArray undistorted, InputArray K, InputArray D, InputArray R, InputArray P)
+void cv::fisheye::undistortPoints( InputArray distorted, OutputArray undistorted, InputArray K, InputArray D,
+                                   InputArray R, InputArray P, TermCriteria criteria)
 {
     CV_INSTRUMENT_REGION();
 
```

Review comment:
"Criteria type, can be one of: COUNT, EPS or COUNT + EPS": https://docs.opencv.org/4.x/d9/d5d/classcv_1_1TermCriteria.html#a56fecdc291ccaba8aad27d67ccf72c57 So need extra condition, if `criteria.epsilon` is valid value, but not random noise.
**File:** modules/calib3d/src/fisheye.cpp
**Change Type:** modified
**Context:** PR #21834: Add termination criteria to cv::fisheye::undistortPoints()

**Code Changes:**
```diff
@@ -318,7 +318,8 @@ void cv::fisheye::distortPoints(InputArray undistorted, OutputArray distorted, I
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
 /// cv::fisheye::undistortPoints
 
-void cv::fisheye::undistortPoints( InputArray distorted, OutputArray undistorted, InputArray K, InputArray D, InputArray R, InputArray P)
+void cv::fisheye::undistortPoints( InputArray distorted, OutputArray undistorted, InputArray K, InputArray D,
+                                   InputArray R, InputArray P, TermCriteria criteria)
 {
     CV_INSTRUMENT_REGION();
 
```

Review comment:
The same here too.
**File:** modules/core/test/test_io.cpp
**Change Type:** modified
**Context:** PR #21864: Add assert to persistance to address security concerns
**Review Line:** 821

**Code Changes:**
```diff
+
+    file.write(data, sizeof(data));
+    file.close();
+
+    // This just shouldn't segfault, otherwise it's fine
+    EXPECT_ANY_THROW(FileStorage(name, FileStorage::READ));
+}
 
 TEST(Core_InputOutput, filestorage_base64_valid_call)
 {
```

Review comment:
`FileStorage` could be initialized from memory buffer. Is the issue is reproducible with bytes array too? If yes, then you can do the test in memory and do not write to disc. See `FileStorage::MEMORY` option: https://docs.opencv.org/4.x/da/d56/classcv_1_1FileStorage.html#a973e41cb75ef6230412a567723b7482d and example: https://github.com/opencv/opencv/blob/66f3c2673cd424a9c282fb0c8622a4ae43d3e81d/samples/cpp/filestorage.cpp#L165
**File:** modules/core/test/test_io.cpp
**Change Type:** modified
**Context:** PR #21864: Add assert to persistance to address security concerns
**Review Line:** 821

**Code Changes:**
```diff
+
+    file.write(data, sizeof(data));
+    file.close();
+
+    // This just shouldn't segfault, otherwise it's fine
+    EXPECT_ANY_THROW(FileStorage(name, FileStorage::READ));
+}
 
 TEST(Core_InputOutput, filestorage_base64_valid_call)
 {
```

Review comment:
This code gets executed only if we're opening the file. Otherwise we return early from this block: https://github.com/opencv/opencv/blob/66f3c2673cd424a9c282fb0c8622a4ae43d3e81d/modules/core/src/persistence.cpp#L784
**File:** .github/workflows/PR-3.4-U20.yaml
**Change Type:** added
**Context:** PR #21875: Added workflow for Github Actions to build and test OpenCV on Linux

**Code Changes:**
```diff
@@ -0,0 +1,167 @@
+name: PR:3.4 U20
+
+on:
+  pull_request:
+    branches:
+      - 3.4
+
+env:
+  EXTRA_CMAKE_OPTIONS: '-DBUILD_DOCS=ON -DPYTHON_DEFAULT_EXECUTABLE=/usr/bin/python3 -DBUILD_EXAMPLES=ON -DOPENCV_ENABLE_NONFREE=ON -DENABLE_CCACHE=OFF'
```

Review comment:
I propose to "echo" the executed command to console. It helps to split tests and reproduce test failure for particular module.