Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv
Commits
1f23202a
Commit
1f23202a
authored
Jul 01, 2017
by
Maksim Shabunin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issues found by static analysis (5th round)
parent
e5aa2135
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
53 additions
and
49 deletions
+53
-49
calibinit.cpp
modules/calib3d/src/calibinit.cpp
+3
-1
datastructs.cpp
modules/core/src/datastructs.cpp
+1
-1
opencl_core.cpp
modules/core/src/opencl/runtime/opencl_core.cpp
+2
-2
contours.cpp
modules/imgproc/src/contours.cpp
+1
-1
convhull.cpp
modules/imgproc/src/convhull.cpp
+11
-19
hough.cpp
modules/imgproc/src/hough.cpp
+20
-23
precomp.hpp
modules/imgproc/src/precomp.hpp
+12
-1
templmatch.cpp
modules/imgproc/src/templmatch.cpp
+1
-0
haar.cpp
modules/objdetect/src/haar.cpp
+1
-1
calibrate.cpp
modules/photo/src/calibrate.cpp
+1
-0
No files found.
modules/calib3d/src/calibinit.cpp
View file @
1f23202a
...
@@ -1836,7 +1836,9 @@ icvGenerateQuads( CvCBQuad **out_quads, CvCBCorner **out_corners,
...
@@ -1836,7 +1836,9 @@ icvGenerateQuads( CvCBQuad **out_quads, CvCBCorner **out_corners,
assert
(
src_contour
->
total
==
4
);
assert
(
src_contour
->
total
==
4
);
for
(
i
=
0
;
i
<
4
;
i
++
)
for
(
i
=
0
;
i
<
4
;
i
++
)
{
{
CvPoint2D32f
pt
=
cvPointTo32f
(
*
(
CvPoint
*
)
cvGetSeqElem
(
src_contour
,
i
));
CvPoint
*
onePoint
=
(
CvPoint
*
)
cvGetSeqElem
(
src_contour
,
i
);
CV_Assert
(
onePoint
!=
NULL
);
CvPoint2D32f
pt
=
cvPointTo32f
(
*
onePoint
);
CvCBCorner
*
corner
=
&
(
*
out_corners
)[
quad_count
*
4
+
i
];
CvCBCorner
*
corner
=
&
(
*
out_corners
)[
quad_count
*
4
+
i
];
memset
(
corner
,
0
,
sizeof
(
*
corner
)
);
memset
(
corner
,
0
,
sizeof
(
*
corner
)
);
...
...
modules/core/src/datastructs.cpp
View file @
1f23202a
...
@@ -2882,7 +2882,7 @@ cvGraphRemoveEdgeByPtr( CvGraph* graph, CvGraphVtx* start_vtx, CvGraphVtx* end_v
...
@@ -2882,7 +2882,7 @@ cvGraphRemoveEdgeByPtr( CvGraph* graph, CvGraphVtx* start_vtx, CvGraphVtx* end_v
break
;
break
;
}
}
a
ssert
(
edge
!=
0
);
CV_A
ssert
(
edge
!=
0
);
next_edge
=
edge
->
next
[
ofs
];
next_edge
=
edge
->
next
[
ofs
];
if
(
prev_edge
)
if
(
prev_edge
)
...
...
modules/core/src/opencl/runtime/opencl_core.cpp
View file @
1f23202a
...
@@ -257,14 +257,14 @@ static void* opencl_check_fn(int ID)
...
@@ -257,14 +257,14 @@ static void* opencl_check_fn(int ID)
const
struct
DynamicFnEntry
*
e
=
NULL
;
const
struct
DynamicFnEntry
*
e
=
NULL
;
if
(
ID
<
CUSTOM_FUNCTION_ID
)
if
(
ID
<
CUSTOM_FUNCTION_ID
)
{
{
a
ssert
(
ID
>=
0
&&
ID
<
(
int
)(
sizeof
(
opencl_fn_list
)
/
sizeof
(
opencl_fn_list
[
0
])));
CV_A
ssert
(
ID
>=
0
&&
ID
<
(
int
)(
sizeof
(
opencl_fn_list
)
/
sizeof
(
opencl_fn_list
[
0
])));
e
=
opencl_fn_list
[
ID
];
e
=
opencl_fn_list
[
ID
];
}
}
#ifdef HAVE_OPENCL_SVM
#ifdef HAVE_OPENCL_SVM
else
if
(
ID
>=
SVM_FUNCTION_ID_START
&&
ID
<
SVM_FUNCTION_ID_END
)
else
if
(
ID
>=
SVM_FUNCTION_ID_START
&&
ID
<
SVM_FUNCTION_ID_END
)
{
{
ID
=
ID
-
SVM_FUNCTION_ID_START
;
ID
=
ID
-
SVM_FUNCTION_ID_START
;
a
ssert
(
ID
>=
0
&&
ID
<
(
int
)(
sizeof
(
opencl_svm_fn_list
)
/
sizeof
(
opencl_svm_fn_list
[
0
])));
CV_A
ssert
(
ID
>=
0
&&
ID
<
(
int
)(
sizeof
(
opencl_svm_fn_list
)
/
sizeof
(
opencl_svm_fn_list
[
0
])));
e
=
opencl_svm_fn_list
[
ID
];
e
=
opencl_svm_fn_list
[
ID
];
}
}
#endif
#endif
...
...
modules/imgproc/src/contours.cpp
View file @
1f23202a
...
@@ -1179,7 +1179,7 @@ cvFindNextContour( CvContourScanner scanner )
...
@@ -1179,7 +1179,7 @@ cvFindNextContour( CvContourScanner scanner )
cur
=
cur
->
next
;
cur
=
cur
->
next
;
}
}
a
ssert
(
par_info
!=
0
);
CV_A
ssert
(
par_info
!=
0
);
/* if current contour is a hole and previous contour is a hole or
/* if current contour is a hole and previous contour is a hole or
current contour is external and previous contour is external then
current contour is external and previous contour is external then
...
...
modules/imgproc/src/convhull.cpp
View file @
1f23202a
...
@@ -404,9 +404,6 @@ CV_IMPL CvSeq*
...
@@ -404,9 +404,6 @@ CV_IMPL CvSeq*
cvConvexHull2
(
const
CvArr
*
array
,
void
*
hull_storage
,
cvConvexHull2
(
const
CvArr
*
array
,
void
*
hull_storage
,
int
orientation
,
int
return_points
)
int
orientation
,
int
return_points
)
{
{
union
{
CvContour
*
c
;
CvSeq
*
s
;
}
hull
;
hull
.
s
=
0
;
CvMat
*
mat
=
0
;
CvMat
*
mat
=
0
;
CvContour
contour_header
;
CvContour
contour_header
;
CvSeq
hull_header
;
CvSeq
hull_header
;
...
@@ -427,7 +424,9 @@ cvConvexHull2( const CvArr* array, void* hull_storage,
...
@@ -427,7 +424,9 @@ cvConvexHull2( const CvArr* array, void* hull_storage,
ptseq
=
cvPointSeqFromMat
(
CV_SEQ_KIND_GENERIC
,
array
,
&
contour_header
,
&
block
);
ptseq
=
cvPointSeqFromMat
(
CV_SEQ_KIND_GENERIC
,
array
,
&
contour_header
,
&
block
);
}
}
if
(
CV_IS_STORAGE
(
hull_storage
))
bool
isStorage
=
isStorageOrMat
(
hull_storage
);
if
(
isStorage
)
{
{
if
(
return_points
)
if
(
return_points
)
{
{
...
@@ -445,9 +444,6 @@ cvConvexHull2( const CvArr* array, void* hull_storage,
...
@@ -445,9 +444,6 @@ cvConvexHull2( const CvArr* array, void* hull_storage,
}
}
else
else
{
{
if
(
!
CV_IS_MAT
(
hull_storage
))
CV_Error
(
CV_StsBadArg
,
"Destination must be valid memory storage or matrix"
);
mat
=
(
CvMat
*
)
hull_storage
;
mat
=
(
CvMat
*
)
hull_storage
;
if
(
(
mat
->
cols
!=
1
&&
mat
->
rows
!=
1
)
||
!
CV_IS_MAT_CONT
(
mat
->
type
))
if
(
(
mat
->
cols
!=
1
&&
mat
->
rows
!=
1
)
||
!
CV_IS_MAT_CONT
(
mat
->
type
))
...
@@ -473,10 +469,10 @@ cvConvexHull2( const CvArr* array, void* hull_storage,
...
@@ -473,10 +469,10 @@ cvConvexHull2( const CvArr* array, void* hull_storage,
int
total
=
ptseq
->
total
;
int
total
=
ptseq
->
total
;
if
(
total
==
0
)
if
(
total
==
0
)
{
{
if
(
mat
)
if
(
!
isStorage
)
CV_Error
(
CV_StsBadSize
,
CV_Error
(
CV_StsBadSize
,
"Point sequence can not be empty if the output is matrix"
);
"Point sequence can not be empty if the output is matrix"
);
return
hull
.
s
;
return
0
;
}
}
cv
::
AutoBuffer
<
double
>
_ptbuf
;
cv
::
AutoBuffer
<
double
>
_ptbuf
;
...
@@ -498,22 +494,18 @@ cvConvexHull2( const CvArr* array, void* hull_storage,
...
@@ -498,22 +494,18 @@ cvConvexHull2( const CvArr* array, void* hull_storage,
else
else
cvSeqPushMulti
(
hullseq
,
h0
.
ptr
(),
(
int
)
h0
.
total
());
cvSeqPushMulti
(
hullseq
,
h0
.
ptr
(),
(
int
)
h0
.
total
());
if
(
mat
)
if
(
isStorage
)
{
return
hullseq
;
}
else
{
{
if
(
mat
->
rows
>
mat
->
cols
)
if
(
mat
->
rows
>
mat
->
cols
)
mat
->
rows
=
hullseq
->
total
;
mat
->
rows
=
hullseq
->
total
;
else
else
mat
->
cols
=
hullseq
->
total
;
mat
->
cols
=
hullseq
->
total
;
return
0
;
}
}
else
{
hull
.
s
=
hullseq
;
hull
.
c
->
rect
=
cvBoundingRect
(
ptseq
,
ptseq
->
header_size
<
(
int
)
sizeof
(
CvContour
)
||
&
ptseq
->
flags
==
&
contour_header
.
flags
);
}
return
hull
.
s
;
}
}
...
...
modules/imgproc/src/hough.cpp
View file @
1f23202a
...
@@ -894,7 +894,6 @@ cvHoughLines2( CvArr* src_image, void* lineStorage, int method,
...
@@ -894,7 +894,6 @@ cvHoughLines2( CvArr* src_image, void* lineStorage, int method,
cv
::
Mat
image
=
cv
::
cvarrToMat
(
src_image
);
cv
::
Mat
image
=
cv
::
cvarrToMat
(
src_image
);
std
::
vector
<
cv
::
Vec2f
>
l2
;
std
::
vector
<
cv
::
Vec2f
>
l2
;
std
::
vector
<
cv
::
Vec4i
>
l4
;
std
::
vector
<
cv
::
Vec4i
>
l4
;
CvSeq
*
result
=
0
;
CvMat
*
mat
=
0
;
CvMat
*
mat
=
0
;
CvSeq
*
lines
=
0
;
CvSeq
*
lines
=
0
;
...
@@ -921,11 +920,13 @@ cvHoughLines2( CvArr* src_image, void* lineStorage, int method,
...
@@ -921,11 +920,13 @@ cvHoughLines2( CvArr* src_image, void* lineStorage, int method,
elemSize
=
sizeof
(
int
)
*
4
;
elemSize
=
sizeof
(
int
)
*
4
;
}
}
if
(
CV_IS_STORAGE
(
lineStorage
))
bool
isStorage
=
isStorageOrMat
(
lineStorage
);
if
(
isStorage
)
{
{
lines
=
cvCreateSeq
(
lineType
,
sizeof
(
CvSeq
),
elemSize
,
(
CvMemStorage
*
)
lineStorage
);
lines
=
cvCreateSeq
(
lineType
,
sizeof
(
CvSeq
),
elemSize
,
(
CvMemStorage
*
)
lineStorage
);
}
}
else
if
(
CV_IS_MAT
(
lineStorage
))
else
{
{
mat
=
(
CvMat
*
)
lineStorage
;
mat
=
(
CvMat
*
)
lineStorage
;
...
@@ -942,8 +943,6 @@ cvHoughLines2( CvArr* src_image, void* lineStorage, int method,
...
@@ -942,8 +943,6 @@ cvHoughLines2( CvArr* src_image, void* lineStorage, int method,
linesMax
=
lines
->
total
;
linesMax
=
lines
->
total
;
cvClearSeq
(
lines
);
cvClearSeq
(
lines
);
}
}
else
CV_Error
(
CV_StsBadArg
,
"Destination is not CvMemStorage* nor CvMat*"
);
iparam1
=
cvRound
(
param1
);
iparam1
=
cvRound
(
param1
);
iparam2
=
cvRound
(
param2
);
iparam2
=
cvRound
(
param2
);
...
@@ -968,7 +967,7 @@ cvHoughLines2( CvArr* src_image, void* lineStorage, int method,
...
@@ -968,7 +967,7 @@ cvHoughLines2( CvArr* src_image, void* lineStorage, int method,
int
nlines
=
(
int
)(
l2
.
size
()
+
l4
.
size
());
int
nlines
=
(
int
)(
l2
.
size
()
+
l4
.
size
());
if
(
mat
)
if
(
!
isStorage
)
{
{
if
(
mat
->
cols
>
mat
->
rows
)
if
(
mat
->
cols
>
mat
->
rows
)
mat
->
cols
=
nlines
;
mat
->
cols
=
nlines
;
...
@@ -981,20 +980,20 @@ cvHoughLines2( CvArr* src_image, void* lineStorage, int method,
...
@@ -981,20 +980,20 @@ cvHoughLines2( CvArr* src_image, void* lineStorage, int method,
cv
::
Mat
lx
=
method
==
CV_HOUGH_STANDARD
||
method
==
CV_HOUGH_MULTI_SCALE
?
cv
::
Mat
lx
=
method
==
CV_HOUGH_STANDARD
||
method
==
CV_HOUGH_MULTI_SCALE
?
cv
::
Mat
(
nlines
,
1
,
CV_32FC2
,
&
l2
[
0
])
:
cv
::
Mat
(
nlines
,
1
,
CV_32SC4
,
&
l4
[
0
]);
cv
::
Mat
(
nlines
,
1
,
CV_32FC2
,
&
l2
[
0
])
:
cv
::
Mat
(
nlines
,
1
,
CV_32SC4
,
&
l4
[
0
]);
if
(
mat
)
if
(
isStorage
)
{
{
cv
::
Mat
dst
(
nlines
,
1
,
lx
.
type
(),
mat
->
data
.
ptr
);
cvSeqPushMulti
(
lines
,
lx
.
ptr
(),
nlines
);
lx
.
copyTo
(
dst
);
}
}
else
else
{
{
cvSeqPushMulti
(
lines
,
lx
.
ptr
(),
nlines
);
cv
::
Mat
dst
(
nlines
,
1
,
lx
.
type
(),
mat
->
data
.
ptr
);
lx
.
copyTo
(
dst
);
}
}
}
}
if
(
!
mat
)
if
(
isStorage
)
re
sult
=
lines
;
re
turn
lines
;
return
result
;
return
0
;
}
}
...
@@ -1227,8 +1226,6 @@ cvHoughCircles( CvArr* src_image, void* circle_storage,
...
@@ -1227,8 +1226,6 @@ cvHoughCircles( CvArr* src_image, void* circle_storage,
double
param1
,
double
param2
,
double
param1
,
double
param2
,
int
min_radius
,
int
max_radius
)
int
min_radius
,
int
max_radius
)
{
{
CvSeq
*
result
=
0
;
CvMat
stub
,
*
img
=
(
CvMat
*
)
src_image
;
CvMat
stub
,
*
img
=
(
CvMat
*
)
src_image
;
CvMat
*
mat
=
0
;
CvMat
*
mat
=
0
;
CvSeq
*
circles
=
0
;
CvSeq
*
circles
=
0
;
...
@@ -1255,12 +1252,14 @@ cvHoughCircles( CvArr* src_image, void* circle_storage,
...
@@ -1255,12 +1252,14 @@ cvHoughCircles( CvArr* src_image, void* circle_storage,
else
if
(
max_radius
<=
min_radius
)
else
if
(
max_radius
<=
min_radius
)
max_radius
=
min_radius
+
2
;
max_radius
=
min_radius
+
2
;
if
(
CV_IS_STORAGE
(
circle_storage
))
bool
isStorage
=
isStorageOrMat
(
circle_storage
);
if
(
isStorage
)
{
{
circles
=
cvCreateSeq
(
CV_32FC3
,
sizeof
(
CvSeq
),
circles
=
cvCreateSeq
(
CV_32FC3
,
sizeof
(
CvSeq
),
sizeof
(
float
)
*
3
,
(
CvMemStorage
*
)
circle_storage
);
sizeof
(
float
)
*
3
,
(
CvMemStorage
*
)
circle_storage
);
}
}
else
if
(
CV_IS_MAT
(
circle_storage
))
else
{
{
mat
=
(
CvMat
*
)
circle_storage
;
mat
=
(
CvMat
*
)
circle_storage
;
...
@@ -1274,8 +1273,6 @@ cvHoughCircles( CvArr* src_image, void* circle_storage,
...
@@ -1274,8 +1273,6 @@ cvHoughCircles( CvArr* src_image, void* circle_storage,
circles_max
=
circles
->
total
;
circles_max
=
circles
->
total
;
cvClearSeq
(
circles
);
cvClearSeq
(
circles
);
}
}
else
CV_Error
(
CV_StsBadArg
,
"Destination is not CvMemStorage* nor CvMat*"
);
switch
(
method
)
switch
(
method
)
{
{
...
@@ -1288,17 +1285,17 @@ cvHoughCircles( CvArr* src_image, void* circle_storage,
...
@@ -1288,17 +1285,17 @@ cvHoughCircles( CvArr* src_image, void* circle_storage,
CV_Error
(
CV_StsBadArg
,
"Unrecognized method id"
);
CV_Error
(
CV_StsBadArg
,
"Unrecognized method id"
);
}
}
if
(
mat
)
if
(
isStorage
)
return
circles
;
else
{
{
if
(
mat
->
cols
>
mat
->
rows
)
if
(
mat
->
cols
>
mat
->
rows
)
mat
->
cols
=
circles
->
total
;
mat
->
cols
=
circles
->
total
;
else
else
mat
->
rows
=
circles
->
total
;
mat
->
rows
=
circles
->
total
;
}
}
else
result
=
circles
;
return
result
;
return
0
;
}
}
...
...
modules/imgproc/src/precomp.hpp
View file @
1f23202a
...
@@ -69,7 +69,7 @@
...
@@ -69,7 +69,7 @@
/* helper tables */
/* helper tables */
extern
const
uchar
icvSaturate8u_cv
[];
extern
const
uchar
icvSaturate8u_cv
[];
#define CV_FAST_CAST_8U(t) (
assert(-256 <= (t) && (t) <= 512), icvSaturate8u_cv[(t)+256]
)
#define CV_FAST_CAST_8U(t) (
(-256 <= (t) && (t) <= 512) ? icvSaturate8u_cv[(t)+256] : 0
)
#define CV_CALC_MIN_8U(a,b) (a) -= CV_FAST_CAST_8U((a) - (b))
#define CV_CALC_MIN_8U(a,b) (a) -= CV_FAST_CAST_8U((a) - (b))
#define CV_CALC_MAX_8U(a,b) (a) += CV_FAST_CAST_8U((b) - (a))
#define CV_CALC_MAX_8U(a,b) (a) += CV_FAST_CAST_8U((b) - (a))
...
@@ -111,4 +111,15 @@ static inline IppiInterpolationType ippiGetInterpolation(int inter)
...
@@ -111,4 +111,15 @@ static inline IppiInterpolationType ippiGetInterpolation(int inter)
#include "opencv2/core/sse_utils.hpp"
#include "opencv2/core/sse_utils.hpp"
inline
bool
isStorageOrMat
(
void
*
arr
)
{
if
(
CV_IS_STORAGE
(
arr
))
return
true
;
else
if
(
CV_IS_MAT
(
arr
))
return
false
;
else
CV_Error
(
CV_StsBadArg
,
"Destination is not CvMemStorage* nor CvMat*"
);
return
false
;
}
#endif
/*__OPENCV_CV_INTERNAL_H_*/
#endif
/*__OPENCV_CV_INTERNAL_H_*/
modules/imgproc/src/templmatch.cpp
View file @
1f23202a
...
@@ -477,6 +477,7 @@ static bool matchTemplate_CCOEFF_NORMED(InputArray _image, InputArray _templ, Ou
...
@@ -477,6 +477,7 @@ static bool matchTemplate_CCOEFF_NORMED(InputArray _image, InputArray _templ, Ou
integral
(
_image
,
image_sums
,
image_sqsums
,
CV_32F
,
CV_32F
);
integral
(
_image
,
image_sums
,
image_sqsums
,
CV_32F
,
CV_32F
);
int
type
=
image_sums
.
type
(),
depth
=
CV_MAT_DEPTH
(
type
),
cn
=
CV_MAT_CN
(
type
);
int
type
=
image_sums
.
type
(),
depth
=
CV_MAT_DEPTH
(
type
),
cn
=
CV_MAT_CN
(
type
);
CV_Assert
(
cn
>=
1
&&
cn
<=
4
);
ocl
::
Kernel
k
(
"matchTemplate_CCOEFF_NORMED"
,
ocl
::
imgproc
::
match_template_oclsrc
,
ocl
::
Kernel
k
(
"matchTemplate_CCOEFF_NORMED"
,
ocl
::
imgproc
::
match_template_oclsrc
,
format
(
"-D CCOEFF_NORMED -D T=%s -D T1=%s -D cn=%d"
,
ocl
::
typeToStr
(
type
),
ocl
::
typeToStr
(
depth
),
cn
));
format
(
"-D CCOEFF_NORMED -D T=%s -D T1=%s -D cn=%d"
,
ocl
::
typeToStr
(
type
),
ocl
::
typeToStr
(
depth
),
cn
));
...
...
modules/objdetect/src/haar.cpp
View file @
1f23202a
...
@@ -1879,7 +1879,7 @@ icvLoadCascadeCART( const char** input_cascade, int n, CvSize orig_window_size )
...
@@ -1879,7 +1879,7 @@ icvLoadCascadeCART( const char** input_cascade, int n, CvSize orig_window_size )
sscanf
(
stage
,
"%d%n"
,
&
rects
,
&
dl
);
sscanf
(
stage
,
"%d%n"
,
&
rects
,
&
dl
);
stage
+=
dl
;
stage
+=
dl
;
CV_
Dbg
Assert
(
rects
>=
2
&&
rects
<=
CV_HAAR_FEATURE_MAX
);
CV_Assert
(
rects
>=
2
&&
rects
<=
CV_HAAR_FEATURE_MAX
);
for
(
k
=
0
;
k
<
rects
;
k
++
)
for
(
k
=
0
;
k
<
rects
;
k
++
)
{
{
...
...
modules/photo/src/calibrate.cpp
View file @
1f23202a
...
@@ -224,6 +224,7 @@ public:
...
@@ -224,6 +224,7 @@ public:
int
channels
=
images
[
0
].
channels
();
int
channels
=
images
[
0
].
channels
();
int
CV_32FCC
=
CV_MAKETYPE
(
CV_32F
,
channels
);
int
CV_32FCC
=
CV_MAKETYPE
(
CV_32F
,
channels
);
CV_Assert
(
channels
>=
1
&&
channels
<=
3
);
dst
.
create
(
LDR_SIZE
,
1
,
CV_32FCC
);
dst
.
create
(
LDR_SIZE
,
1
,
CV_32FCC
);
Mat
response
=
dst
.
getMat
();
Mat
response
=
dst
.
getMat
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment