Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
git2
Overview
Overview
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
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
git2
Commits
bea65980
Unverified
Commit
bea65980
authored
Oct 25, 2018
by
Patrick Steinhardt
Committed by
GitHub
Oct 25, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #4851 from pks-t/pks/strtol-removal
strtol removal
parents
11945461
ea19efc1
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
110 additions
and
65 deletions
+110
-65
src/commit_list.c
+3
-1
src/config.c
+1
-1
src/index.c
+1
-1
src/rebase.c
+1
-1
src/revparse.c
+3
-2
src/signature.c
+4
-2
src/streams/curl.c
+1
-1
src/transports/smart_pkt.c
+1
-1
src/transports/winhttp.c
+2
-1
src/tree-cache.c
+2
-2
src/util.c
+20
-18
src/util.h
+0
-2
tests/core/strtol.c
+71
-32
No files found.
src/commit_list.c
View file @
bea65980
...
@@ -171,7 +171,9 @@ static int commit_quick_parse(
...
@@ -171,7 +171,9 @@ static int commit_quick_parse(
buffer
--
;
buffer
--
;
}
}
if
((
buffer
==
committer_start
)
||
(
git__strtol64
(
&
commit_time
,
(
char
*
)(
buffer
+
1
),
NULL
,
10
)
<
0
))
if
((
buffer
==
committer_start
)
||
(
git__strntol64
(
&
commit_time
,
(
char
*
)(
buffer
+
1
),
buffer_end
-
buffer
+
1
,
NULL
,
10
)
<
0
))
return
commit_error
(
commit
,
"cannot parse commit time"
);
return
commit_error
(
commit
,
"cannot parse commit time"
);
commit
->
time
=
commit_time
;
commit
->
time
=
commit_time
;
...
...
src/config.c
View file @
bea65980
...
@@ -1300,7 +1300,7 @@ int git_config_parse_int64(int64_t *out, const char *value)
...
@@ -1300,7 +1300,7 @@ int git_config_parse_int64(int64_t *out, const char *value)
const
char
*
num_end
;
const
char
*
num_end
;
int64_t
num
;
int64_t
num
;
if
(
!
value
||
git__str
tol64
(
&
num
,
value
,
&
num_end
,
0
)
<
0
)
if
(
!
value
||
git__str
ntol64
(
&
num
,
value
,
strlen
(
value
)
,
&
num_end
,
0
)
<
0
)
goto
fail_parse
;
goto
fail_parse
;
switch
(
*
num_end
)
{
switch
(
*
num_end
)
{
...
...
src/index.c
View file @
bea65980
...
@@ -2243,7 +2243,7 @@ static int read_reuc(git_index *index, const char *buffer, size_t size)
...
@@ -2243,7 +2243,7 @@ static int read_reuc(git_index *index, const char *buffer, size_t size)
for
(
i
=
0
;
i
<
3
;
i
++
)
{
for
(
i
=
0
;
i
<
3
;
i
++
)
{
int64_t
tmp
;
int64_t
tmp
;
if
(
git__str
tol64
(
&
tmp
,
buffer
,
&
endptr
,
8
)
<
0
||
if
(
git__str
ntol64
(
&
tmp
,
buffer
,
size
,
&
endptr
,
8
)
<
0
||
!
endptr
||
endptr
==
buffer
||
*
endptr
||
!
endptr
||
endptr
==
buffer
||
*
endptr
||
tmp
<
0
||
tmp
>
UINT32_MAX
)
{
tmp
<
0
||
tmp
>
UINT32_MAX
)
{
index_entry_reuc_free
(
lost
);
index_entry_reuc_free
(
lost
);
...
...
src/rebase.c
View file @
bea65980
...
@@ -152,7 +152,7 @@ GIT_INLINE(int) rebase_readint(
...
@@ -152,7 +152,7 @@ GIT_INLINE(int) rebase_readint(
if
((
error
=
rebase_readfile
(
asc_out
,
state_path
,
filename
))
<
0
)
if
((
error
=
rebase_readfile
(
asc_out
,
state_path
,
filename
))
<
0
)
return
error
;
return
error
;
if
(
git__str
tol32
(
&
num
,
asc_out
->
ptr
,
&
eol
,
10
)
<
0
||
num
<
0
||
*
eol
)
{
if
(
git__str
ntol32
(
&
num
,
asc_out
->
ptr
,
asc_out
->
size
,
&
eol
,
10
)
<
0
||
num
<
0
||
*
eol
)
{
giterr_set
(
GITERR_REBASE
,
"the file '%s' contains an invalid numeric value"
,
filename
);
giterr_set
(
GITERR_REBASE
,
"the file '%s' contains an invalid numeric value"
,
filename
);
return
-
1
;
return
-
1
;
}
}
...
...
src/revparse.c
View file @
bea65980
...
@@ -128,7 +128,8 @@ static int try_parse_numeric(int *n, const char *curly_braces_content)
...
@@ -128,7 +128,8 @@ static int try_parse_numeric(int *n, const char *curly_braces_content)
int32_t
content
;
int32_t
content
;
const
char
*
end_ptr
;
const
char
*
end_ptr
;
if
(
git__strtol32
(
&
content
,
curly_braces_content
,
&
end_ptr
,
10
)
<
0
)
if
(
git__strntol32
(
&
content
,
curly_braces_content
,
strlen
(
curly_braces_content
),
&
end_ptr
,
10
)
<
0
)
return
-
1
;
return
-
1
;
if
(
*
end_ptr
!=
'\0'
)
if
(
*
end_ptr
!=
'\0'
)
...
@@ -578,7 +579,7 @@ static int extract_how_many(int *n, const char *spec, size_t *pos)
...
@@ -578,7 +579,7 @@ static int extract_how_many(int *n, const char *spec, size_t *pos)
}
while
(
spec
[(
*
pos
)]
==
kind
&&
kind
==
'~'
);
}
while
(
spec
[(
*
pos
)]
==
kind
&&
kind
==
'~'
);
if
(
git__isdigit
(
spec
[
*
pos
]))
{
if
(
git__isdigit
(
spec
[
*
pos
]))
{
if
(
git__str
tol32
(
&
parsed
,
spec
+
*
pos
,
&
end_ptr
,
10
)
<
0
)
if
(
git__str
ntol32
(
&
parsed
,
spec
+
*
pos
,
strlen
(
spec
+
*
pos
)
,
&
end_ptr
,
10
)
<
0
)
return
GIT_EINVALIDSPEC
;
return
GIT_EINVALIDSPEC
;
accumulated
+=
(
parsed
-
1
);
accumulated
+=
(
parsed
-
1
);
...
...
src/signature.c
View file @
bea65980
...
@@ -231,7 +231,8 @@ int git_signature__parse(git_signature *sig, const char **buffer_out,
...
@@ -231,7 +231,8 @@ int git_signature__parse(git_signature *sig, const char **buffer_out,
const
char
*
time_start
=
email_end
+
2
;
const
char
*
time_start
=
email_end
+
2
;
const
char
*
time_end
;
const
char
*
time_end
;
if
(
git__strtol64
(
&
sig
->
when
.
time
,
time_start
,
&
time_end
,
10
)
<
0
)
{
if
(
git__strntol64
(
&
sig
->
when
.
time
,
time_start
,
buffer_end
-
time_start
,
&
time_end
,
10
)
<
0
)
{
git__free
(
sig
->
name
);
git__free
(
sig
->
name
);
git__free
(
sig
->
email
);
git__free
(
sig
->
email
);
sig
->
name
=
sig
->
email
=
NULL
;
sig
->
name
=
sig
->
email
=
NULL
;
...
@@ -246,7 +247,8 @@ int git_signature__parse(git_signature *sig, const char **buffer_out,
...
@@ -246,7 +247,8 @@ int git_signature__parse(git_signature *sig, const char **buffer_out,
tz_start
=
time_end
+
1
;
tz_start
=
time_end
+
1
;
if
((
tz_start
[
0
]
!=
'-'
&&
tz_start
[
0
]
!=
'+'
)
||
if
((
tz_start
[
0
]
!=
'-'
&&
tz_start
[
0
]
!=
'+'
)
||
git__strtol32
(
&
offset
,
tz_start
+
1
,
&
tz_end
,
10
)
<
0
)
{
git__strntol32
(
&
offset
,
tz_start
+
1
,
buffer_end
-
tz_start
+
1
,
&
tz_end
,
10
)
<
0
)
{
/* malformed timezone, just assume it's zero */
/* malformed timezone, just assume it's zero */
offset
=
0
;
offset
=
0
;
}
}
...
...
src/streams/curl.c
View file @
bea65980
...
@@ -330,7 +330,7 @@ int git_curl_stream_new(git_stream **out, const char *host, const char *port)
...
@@ -330,7 +330,7 @@ int git_curl_stream_new(git_stream **out, const char *host, const char *port)
return
-
1
;
return
-
1
;
}
}
if
((
error
=
git__str
tol32
(
&
iport
,
port
,
NULL
,
10
))
<
0
)
{
if
((
error
=
git__str
ntol32
(
&
iport
,
port
,
strlen
(
port
)
,
NULL
,
10
))
<
0
)
{
git__free
(
st
);
git__free
(
st
);
return
error
;
return
error
;
}
}
...
...
src/transports/smart_pkt.c
View file @
bea65980
...
@@ -391,7 +391,7 @@ static int parse_len(size_t *out, const char *line, size_t linelen)
...
@@ -391,7 +391,7 @@ static int parse_len(size_t *out, const char *line, size_t linelen)
}
}
}
}
if
((
error
=
git__str
tol32
(
&
len
,
num
,
&
num_end
,
16
))
<
0
)
if
((
error
=
git__str
ntol32
(
&
len
,
num
,
PKT_LEN_SIZE
,
&
num_end
,
16
))
<
0
)
return
error
;
return
error
;
if
(
len
<
0
)
if
(
len
<
0
)
...
...
src/transports/winhttp.c
View file @
bea65980
...
@@ -766,7 +766,8 @@ static int winhttp_connect(
...
@@ -766,7 +766,8 @@ static int winhttp_connect(
t
->
connection
=
NULL
;
t
->
connection
=
NULL
;
/* Prepare port */
/* Prepare port */
if
(
git__strtol32
(
&
port
,
t
->
connection_data
.
port
,
NULL
,
10
)
<
0
)
if
(
git__strntol32
(
&
port
,
t
->
connection_data
.
port
,
strlen
(
t
->
connection_data
.
port
),
NULL
,
10
)
<
0
)
return
-
1
;
return
-
1
;
/* Prepare host */
/* Prepare host */
...
...
src/tree-cache.c
View file @
bea65980
...
@@ -91,7 +91,7 @@ static int read_tree_internal(git_tree_cache **out,
...
@@ -91,7 +91,7 @@ static int read_tree_internal(git_tree_cache **out,
return
-
1
;
return
-
1
;
/* Blank-terminated ASCII decimal number of entries in this tree */
/* Blank-terminated ASCII decimal number of entries in this tree */
if
(
git__str
tol32
(
&
count
,
buffer
,
&
buffer
,
10
)
<
0
)
if
(
git__str
ntol32
(
&
count
,
buffer
,
buffer_end
-
buffer
,
&
buffer
,
10
)
<
0
)
goto
corrupted
;
goto
corrupted
;
tree
->
entry_count
=
count
;
tree
->
entry_count
=
count
;
...
@@ -100,7 +100,7 @@ static int read_tree_internal(git_tree_cache **out,
...
@@ -100,7 +100,7 @@ static int read_tree_internal(git_tree_cache **out,
goto
corrupted
;
goto
corrupted
;
/* Number of children of the tree, newline-terminated */
/* Number of children of the tree, newline-terminated */
if
(
git__str
tol32
(
&
count
,
buffer
,
&
buffer
,
10
)
<
0
||
count
<
0
)
if
(
git__str
ntol32
(
&
count
,
buffer
,
buffer_end
-
buffer
,
&
buffer
,
10
)
<
0
||
count
<
0
)
goto
corrupted
;
goto
corrupted
;
tree
->
children_count
=
count
;
tree
->
children_count
=
count
;
...
...
src/util.c
View file @
bea65980
...
@@ -68,12 +68,6 @@ int git_strarray_copy(git_strarray *tgt, const git_strarray *src)
...
@@ -68,12 +68,6 @@ int git_strarray_copy(git_strarray *tgt, const git_strarray *src)
return
0
;
return
0
;
}
}
int
git__strtol64
(
int64_t
*
result
,
const
char
*
nptr
,
const
char
**
endptr
,
int
base
)
{
return
git__strntol64
(
result
,
nptr
,
(
size_t
)
-
1
,
endptr
,
base
);
}
int
git__strntol64
(
int64_t
*
result
,
const
char
*
nptr
,
size_t
nptr_len
,
const
char
**
endptr
,
int
base
)
int
git__strntol64
(
int64_t
*
result
,
const
char
*
nptr
,
size_t
nptr_len
,
const
char
**
endptr
,
int
base
)
{
{
const
char
*
p
;
const
char
*
p
;
...
@@ -132,10 +126,20 @@ int git__strntol64(int64_t *result, const char *nptr, size_t nptr_len, const cha
...
@@ -132,10 +126,20 @@ int git__strntol64(int64_t *result, const char *nptr, size_t nptr_len, const cha
v
=
c
-
'A'
+
10
;
v
=
c
-
'A'
+
10
;
if
(
v
>=
base
)
if
(
v
>=
base
)
break
;
break
;
nn
=
n
*
base
+
(
neg
?
-
v
:
v
)
;
v
=
neg
?
-
v
:
v
;
if
(
(
!
neg
&&
nn
<
n
)
||
(
neg
&&
nn
>
n
))
if
(
n
>
INT64_MAX
/
base
||
n
<
INT64_MIN
/
base
)
{
ovfl
=
1
;
ovfl
=
1
;
n
=
nn
;
/* Keep on iterating until the end of this number */
continue
;
}
nn
=
n
*
base
;
if
((
v
>
0
&&
nn
>
INT64_MAX
-
v
)
||
(
v
<
0
&&
nn
<
INT64_MIN
-
v
))
{
ovfl
=
1
;
/* Keep on iterating until the end of this number */
continue
;
}
n
=
nn
+
v
;
}
}
Return:
Return:
...
@@ -156,28 +160,26 @@ Return:
...
@@ -156,28 +160,26 @@ Return:
return
0
;
return
0
;
}
}
int
git__strtol32
(
int32_t
*
result
,
const
char
*
nptr
,
const
char
**
endptr
,
int
base
)
{
return
git__strntol32
(
result
,
nptr
,
(
size_t
)
-
1
,
endptr
,
base
);
}
int
git__strntol32
(
int32_t
*
result
,
const
char
*
nptr
,
size_t
nptr_len
,
const
char
**
endptr
,
int
base
)
int
git__strntol32
(
int32_t
*
result
,
const
char
*
nptr
,
size_t
nptr_len
,
const
char
**
endptr
,
int
base
)
{
{
int
erro
r
;
const
char
*
tmp_endpt
r
;
int32_t
tmp_int
;
int32_t
tmp_int
;
int64_t
tmp_long
;
int64_t
tmp_long
;
int
error
;
if
((
error
=
git__strntol64
(
&
tmp_long
,
nptr
,
nptr_len
,
endptr
,
base
))
<
0
)
if
((
error
=
git__strntol64
(
&
tmp_long
,
nptr
,
nptr_len
,
&
tmp_
endptr
,
base
))
<
0
)
return
error
;
return
error
;
tmp_int
=
tmp_long
&
0xFFFFFFFF
;
tmp_int
=
tmp_long
&
0xFFFFFFFF
;
if
(
tmp_int
!=
tmp_long
)
{
if
(
tmp_int
!=
tmp_long
)
{
giterr_set
(
GITERR_INVALID
,
"failed to convert: '%s' is too large"
,
nptr
);
int
len
=
tmp_endptr
-
nptr
;
giterr_set
(
GITERR_INVALID
,
"failed to convert: '%.*s' is too large"
,
len
,
nptr
);
return
-
1
;
return
-
1
;
}
}
*
result
=
tmp_int
;
*
result
=
tmp_int
;
if
(
endptr
)
*
endptr
=
tmp_endptr
;
return
error
;
return
error
;
}
}
...
...
src/util.h
View file @
bea65980
...
@@ -58,9 +58,7 @@ GIT_INLINE(int) git__signum(int val)
...
@@ -58,9 +58,7 @@ GIT_INLINE(int) git__signum(int val)
return
((
val
>
0
)
-
(
val
<
0
));
return
((
val
>
0
)
-
(
val
<
0
));
}
}
extern
int
git__strtol32
(
int32_t
*
n
,
const
char
*
buff
,
const
char
**
end_buf
,
int
base
);
extern
int
git__strntol32
(
int32_t
*
n
,
const
char
*
buff
,
size_t
buff_len
,
const
char
**
end_buf
,
int
base
);
extern
int
git__strntol32
(
int32_t
*
n
,
const
char
*
buff
,
size_t
buff_len
,
const
char
**
end_buf
,
int
base
);
extern
int
git__strtol64
(
int64_t
*
n
,
const
char
*
buff
,
const
char
**
end_buf
,
int
base
);
extern
int
git__strntol64
(
int64_t
*
n
,
const
char
*
buff
,
size_t
buff_len
,
const
char
**
end_buf
,
int
base
);
extern
int
git__strntol64
(
int64_t
*
n
,
const
char
*
buff
,
size_t
buff_len
,
const
char
**
end_buf
,
int
base
);
...
...
tests/core/strtol.c
View file @
bea65980
#include "clar_libgit2.h"
#include "clar_libgit2.h"
void
test_core_strtol__int32
(
void
)
static
void
assert_l32_parses
(
const
char
*
string
,
int32_t
expected
,
int
base
)
{
{
int32_t
i
;
int32_t
i
;
cl_git_pass
(
git__strntol32
(
&
i
,
string
,
strlen
(
string
),
NULL
,
base
));
cl_assert_equal_i
(
i
,
expected
);
}
cl_git_pass
(
git__strtol32
(
&
i
,
"123"
,
NULL
,
10
));
static
void
assert_l32_fails
(
const
char
*
string
,
int
base
)
cl_assert
(
i
==
123
);
{
cl_git_pass
(
git__strtol32
(
&
i
,
" +123 "
,
NULL
,
10
));
int32_t
i
;
cl_assert
(
i
==
123
);
cl_git_fail
(
git__strntol32
(
&
i
,
string
,
strlen
(
string
),
NULL
,
base
));
cl_git_pass
(
git__strtol32
(
&
i
,
" +2147483647 "
,
NULL
,
10
));
}
cl_assert
(
i
==
2147483647
);
cl_git_pass
(
git__strtol32
(
&
i
,
" -2147483648 "
,
NULL
,
10
));
cl_assert
(
i
==
-
2147483648LL
);
cl_git_fail
(
git__strtol32
(
&
i
,
" 2147483657 "
,
NULL
,
10
));
static
void
assert_l64_parses
(
const
char
*
string
,
int64_t
expected
,
int
base
)
cl_git_fail
(
git__strtol32
(
&
i
,
" -2147483657 "
,
NULL
,
10
));
{
int64_t
i
;
cl_git_pass
(
git__strntol64
(
&
i
,
string
,
strlen
(
string
),
NULL
,
base
));
cl_assert_equal_i
(
i
,
expected
);
}
}
void
test_core_strtol__int64
(
void
)
static
void
assert_l64_fails
(
const
char
*
string
,
int
base
)
{
{
int64_t
i
;
int64_t
i
;
cl_git_fail
(
git__strntol64
(
&
i
,
string
,
strlen
(
string
),
NULL
,
base
));
}
void
test_core_strtol__int32
(
void
)
{
assert_l32_parses
(
"123"
,
123
,
10
);
assert_l32_parses
(
" +123 "
,
123
,
10
);
assert_l32_parses
(
" +2147483647 "
,
2147483647
,
10
);
assert_l32_parses
(
" -2147483648 "
,
-
2147483648LL
,
10
);
assert_l32_parses
(
"A"
,
10
,
16
);
assert_l32_parses
(
"1x1"
,
1
,
10
);
cl_git_pass
(
git__strtol64
(
&
i
,
"123"
,
NULL
,
10
));
assert_l32_fails
(
""
,
10
);
cl_assert
(
i
==
123
);
assert_l32_fails
(
"a"
,
10
);
cl_git_pass
(
git__strtol64
(
&
i
,
" +123 "
,
NULL
,
10
));
assert_l32_fails
(
"x10x"
,
10
);
cl_assert
(
i
==
123
);
assert_l32_fails
(
" 2147483657 "
,
10
);
cl_git_pass
(
git__strtol64
(
&
i
,
" +2147483647 "
,
NULL
,
10
));
assert_l32_fails
(
" -2147483657 "
,
10
);
cl_assert
(
i
==
2147483647
);
cl_git_pass
(
git__strtol64
(
&
i
,
" -2147483648 "
,
NULL
,
10
));
cl_assert
(
i
==
-
2147483648LL
);
cl_git_pass
(
git__strtol64
(
&
i
,
" 2147483657 "
,
NULL
,
10
));
cl_assert
(
i
==
2147483657LL
);
cl_git_pass
(
git__strtol64
(
&
i
,
" -2147483657 "
,
NULL
,
10
));
cl_assert
(
i
==
-
2147483657LL
);
cl_git_pass
(
git__strtol64
(
&
i
,
" 9223372036854775807 "
,
NULL
,
10
));
cl_assert
(
i
==
INT64_MAX
);
cl_git_pass
(
git__strtol64
(
&
i
,
" -9223372036854775808 "
,
NULL
,
10
));
cl_assert
(
i
==
INT64_MIN
);
cl_git_pass
(
git__strtol64
(
&
i
,
" 0x7fffffffffffffff "
,
NULL
,
16
));
cl_assert
(
i
==
INT64_MAX
);
cl_git_pass
(
git__strtol64
(
&
i
,
" -0x8000000000000000 "
,
NULL
,
16
));
cl_assert
(
i
==
INT64_MIN
);
}
}
void
test_core_strtol__int64
(
void
)
{
assert_l64_parses
(
"123"
,
123
,
10
);
assert_l64_parses
(
" +123 "
,
123
,
10
);
assert_l64_parses
(
" +2147483647 "
,
2147483647
,
10
);
assert_l64_parses
(
" -2147483648 "
,
-
2147483648LL
,
10
);
assert_l64_parses
(
" 2147483657 "
,
2147483657LL
,
10
);
assert_l64_parses
(
" -2147483657 "
,
-
2147483657LL
,
10
);
assert_l64_parses
(
" 9223372036854775807 "
,
INT64_MAX
,
10
);
assert_l64_parses
(
" -9223372036854775808 "
,
INT64_MIN
,
10
);
assert_l64_parses
(
" 0x7fffffffffffffff "
,
INT64_MAX
,
16
);
assert_l64_parses
(
" -0x8000000000000000 "
,
INT64_MIN
,
16
);
assert_l64_parses
(
"1a"
,
26
,
16
);
assert_l64_parses
(
"1A"
,
26
,
16
);
assert_l64_fails
(
""
,
10
);
assert_l64_fails
(
"a"
,
10
);
assert_l64_fails
(
"x10x"
,
10
);
assert_l64_fails
(
"0x8000000000000000"
,
16
);
assert_l64_fails
(
"-0x8000000000000001"
,
16
);
}
void
test_core_strtol__buffer_length_truncates
(
void
)
{
int32_t
i32
;
int64_t
i64
;
cl_git_pass
(
git__strntol32
(
&
i32
,
"11"
,
1
,
NULL
,
10
));
cl_assert_equal_i
(
i32
,
1
);
cl_git_pass
(
git__strntol64
(
&
i64
,
"11"
,
1
,
NULL
,
10
));
cl_assert_equal_i
(
i64
,
1
);
}
void
test_core_strtol__error_message_cuts_off
(
void
)
{
assert_l32_fails
(
"2147483657foobar"
,
10
);
cl_assert
(
strstr
(
giterr_last
()
->
message
,
"2147483657"
)
!=
NULL
);
cl_assert
(
strstr
(
giterr_last
()
->
message
,
"foobar"
)
==
NULL
);
}
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