Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
rt-UA
open62541
Commits
e4c166f6
Commit
e4c166f6
authored
5 years ago
by
Julius Pfrommer
Committed by
Julius Pfrommer
5 years ago
Browse files
Options
Download
Email Patches
Plain Diff
feat(core): Parsing of human readable ExpandedNodeId
parent
14c69ad6
master
fix/warn_fuzz
pack/master
No related merge requests found
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
include/open62541/types.h
+20
-0
include/open62541/types.h
src/ua_types_lex.c
+261
-2
src/ua_types_lex.c
src/ua_types_lex.re
+48
-1
src/ua_types_lex.re
tests/check_types_parse.c
+42
-0
tests/check_types_parse.c
with
371 additions
and
3 deletions
+371
-3
include/open62541/types.h
View file @
e4c166f6
...
...
@@ -443,6 +443,26 @@ typedef struct {
UA_EXPORT
extern
const
UA_ExpandedNodeId
UA_EXPANDEDNODEID_NULL
;
#ifdef UA_ENABLE_PARSING
/* Parse the ExpandedNodeId format defined in Part 6, 5.3.1.11:
*
* svr=<serverindex>;ns=<namespaceindex>;<type>=<value>
* or
* svr=<serverindex>;nsu=<uri>;<type>=<value>
*
* The definitions for svr, ns and nsu can be omitted and will be set to zero /
* the empty string.*/
UA_StatusCode
UA_ExpandedNodeId_parse
(
UA_ExpandedNodeId
*
id
,
const
UA_String
str
);
static
UA_INLINE
UA_ExpandedNodeId
UA_EXPANDEDNODEID
(
const
char
*
chars
)
{
UA_ExpandedNodeId
id
;
UA_ExpandedNodeId_parse
(
&
id
,
UA_STRING
((
char
*
)(
uintptr_t
)
chars
));
return
id
;
}
#endif
/** The following functions are shorthand for creating ExpandedNodeIds. */
static
UA_INLINE
UA_ExpandedNodeId
UA_EXPANDEDNODEID_NUMERIC
(
UA_UInt16
nsIndex
,
UA_UInt32
identifier
)
{
...
...
This diff is collapsed.
Click to expand it.
src/ua_types_lex.c
View file @
e4c166f6
...
...
@@ -24,7 +24,7 @@
* In order that users of the SDK don't need to install re2c, always commit a
* recent ua_types_lex.c if changes are made to the lexer. */
const
char
*
yyt1
;
const
char
*
yyt2
;
const
char
*
yyt1
;
const
char
*
yyt2
;
const
char
*
yyt3
;
const
char
*
yyt4
;
static
UA_StatusCode
...
...
@@ -161,6 +161,7 @@ yy6:
return
UA_STATUSCODE_BADINTERNALERROR
;
id
->
namespaceIndex
=
(
UA_UInt16
)
tmp
;
}
/* From the current position until the end of the input */
return
parse_nodeid_body
(
id
,
&
input
[
-
2
],
end
);
}
...
...
@@ -234,6 +235,264 @@ UA_NodeId_parse(UA_NodeId *id, const UA_String str) {
UA_StatusCode
res
=
parse_nodeid
(
id
,
(
const
char
*
)
str
.
data
,
(
const
char
*
)
str
.
data
+
str
.
length
);
if
(
res
!=
UA_STATUSCODE_GOOD
)
*
id
=
UA_NODEID_NULL
;
UA_NodeId_clear
(
id
);
return
res
;
}
static
UA_StatusCode
parse_expandednodeid
(
UA_ExpandedNodeId
*
id
,
const
char
*
input
,
const
char
*
end
)
{
*
id
=
UA_EXPANDEDNODEID_NULL
;
/* Reset the NodeId */
const
char
*
pos
=
input
,
*
svr
=
NULL
,
*
svre
=
NULL
,
*
nsu
=
NULL
,
*
ns
=
NULL
,
*
body
=
NULL
;
{
char
yych
;
if
((
end
-
input
)
<
7
)
goto
error
;
yych
=
*
input
;
switch
(
yych
)
{
case
'b'
:
case
'g'
:
case
'i'
:
yyt1
=
yyt2
=
yyt3
=
yyt4
=
NULL
;
goto
yy19
;
case
'n'
:
yyt1
=
yyt2
=
NULL
;
goto
yy20
;
case
's'
:
yyt1
=
yyt2
=
yyt3
=
yyt4
=
NULL
;
goto
yy21
;
default:
goto
yy17
;
}
yy17:
++
input
;
yy18:
{
error
:
return
UA_STATUSCODE_BADINTERNALERROR
;
}
yy19:
yych
=
*++
input
;
switch
(
yych
)
{
case
'='
:
goto
yy22
;
default:
goto
yy18
;
}
yy20:
yych
=
*
(
pos
=
++
input
);
switch
(
yych
)
{
case
's'
:
goto
yy24
;
default:
goto
yy18
;
}
yy21:
yych
=
*
(
pos
=
++
input
);
switch
(
yych
)
{
case
'='
:
goto
yy22
;
case
'v'
:
goto
yy26
;
default:
goto
yy18
;
}
yy22:
++
input
;
svr
=
yyt1
;
svre
=
yyt2
;
ns
=
yyt3
;
nsu
=
yyt4
;
body
=
input
-
2
;
{
if
(
svr
)
{
size_t
len
=
(
size_t
)((
svre
)
-
svr
);
if
(
UA_readNumber
((
const
UA_Byte
*
)
svr
,
len
,
&
id
->
serverIndex
)
!=
len
)
return
UA_STATUSCODE_BADINTERNALERROR
;
}
if
(
nsu
)
{
size_t
len
=
(
size_t
)((
body
-
1
)
-
nsu
);
UA_String
nsuri
;
nsuri
.
data
=
(
UA_Byte
*
)(
uintptr_t
)
nsu
;
nsuri
.
length
=
len
;
UA_StatusCode
res
=
UA_String_copy
(
&
nsuri
,
&
id
->
namespaceUri
);
if
(
res
!=
UA_STATUSCODE_GOOD
)
return
res
;
}
else
if
(
ns
)
{
UA_UInt32
tmp
;
size_t
len
=
(
size_t
)((
body
-
1
)
-
ns
);
if
(
UA_readNumber
((
const
UA_Byte
*
)
ns
,
len
,
&
tmp
)
!=
len
)
return
UA_STATUSCODE_BADINTERNALERROR
;
id
->
nodeId
.
namespaceIndex
=
(
UA_UInt16
)
tmp
;
}
/* From the current position until the end of the input */
return
parse_nodeid_body
(
&
id
->
nodeId
,
&
input
[
-
2
],
end
);
}
yy24:
yych
=
*++
input
;
switch
(
yych
)
{
case
'='
:
goto
yy27
;
case
'u'
:
goto
yy28
;
default:
goto
yy25
;
}
yy25:
input
=
pos
;
goto
yy18
;
yy26:
yych
=
*++
input
;
switch
(
yych
)
{
case
'r'
:
goto
yy29
;
default:
goto
yy25
;
}
yy27:
yych
=
*++
input
;
switch
(
yych
)
{
case
'0'
:
case
'1'
:
case
'2'
:
case
'3'
:
case
'4'
:
case
'5'
:
case
'6'
:
case
'7'
:
case
'8'
:
case
'9'
:
yyt3
=
input
;
goto
yy30
;
default:
goto
yy25
;
}
yy28:
yych
=
*++
input
;
switch
(
yych
)
{
case
'='
:
goto
yy32
;
default:
goto
yy25
;
}
yy29:
yych
=
*++
input
;
switch
(
yych
)
{
case
'='
:
goto
yy33
;
default:
goto
yy25
;
}
yy30:
++
input
;
if
((
end
-
input
)
<
3
)
goto
error
;
yych
=
*
input
;
switch
(
yych
)
{
case
'0'
:
case
'1'
:
case
'2'
:
case
'3'
:
case
'4'
:
case
'5'
:
case
'6'
:
case
'7'
:
case
'8'
:
case
'9'
:
goto
yy30
;
case
';'
:
goto
yy34
;
default:
goto
yy25
;
}
yy32:
yych
=
*++
input
;
switch
(
yych
)
{
case
'\n'
:
goto
yy25
;
case
';'
:
yyt4
=
input
;
goto
yy37
;
default:
yyt4
=
input
;
goto
yy35
;
}
yy33:
yych
=
*++
input
;
switch
(
yych
)
{
case
'0'
:
case
'1'
:
case
'2'
:
case
'3'
:
case
'4'
:
case
'5'
:
case
'6'
:
case
'7'
:
case
'8'
:
case
'9'
:
yyt1
=
input
;
goto
yy38
;
default:
goto
yy25
;
}
yy34:
yych
=
*++
input
;
switch
(
yych
)
{
case
'b'
:
case
'g'
:
case
'i'
:
case
's'
:
yyt4
=
NULL
;
goto
yy40
;
default:
goto
yy25
;
}
yy35:
++
input
;
if
((
end
-
input
)
<
3
)
goto
error
;
yych
=
*
input
;
switch
(
yych
)
{
case
'\n'
:
goto
yy25
;
case
';'
:
goto
yy37
;
default:
goto
yy35
;
}
yy37:
yych
=
*++
input
;
switch
(
yych
)
{
case
'b'
:
case
'g'
:
case
'i'
:
case
's'
:
yyt3
=
NULL
;
goto
yy40
;
default:
goto
yy25
;
}
yy38:
++
input
;
if
((
end
-
input
)
<
8
)
goto
error
;
yych
=
*
input
;
switch
(
yych
)
{
case
'0'
:
case
'1'
:
case
'2'
:
case
'3'
:
case
'4'
:
case
'5'
:
case
'6'
:
case
'7'
:
case
'8'
:
case
'9'
:
goto
yy38
;
case
';'
:
yyt2
=
input
;
goto
yy41
;
default:
goto
yy25
;
}
yy40:
yych
=
*++
input
;
switch
(
yych
)
{
case
'='
:
goto
yy22
;
default:
goto
yy25
;
}
yy41:
yych
=
*++
input
;
switch
(
yych
)
{
case
'b'
:
case
'g'
:
case
'i'
:
case
's'
:
yyt3
=
yyt4
=
NULL
;
goto
yy40
;
case
'n'
:
goto
yy42
;
default:
goto
yy25
;
}
yy42:
yych
=
*++
input
;
switch
(
yych
)
{
case
's'
:
goto
yy24
;
default:
goto
yy25
;
}
}
}
UA_StatusCode
UA_ExpandedNodeId_parse
(
UA_ExpandedNodeId
*
id
,
const
UA_String
str
)
{
UA_StatusCode
res
=
parse_expandednodeid
(
id
,
(
const
char
*
)
str
.
data
,
(
const
char
*
)
str
.
data
+
str
.
length
);
if
(
res
!=
UA_STATUSCODE_GOOD
)
UA_ExpandedNodeId_clear
(
id
);
return
res
;
}
This diff is collapsed.
Click to expand it.
src/ua_types_lex.re
View file @
e4c166f6
...
...
@@ -137,6 +137,7 @@ parse_nodeid(UA_NodeId *id, const char *input, const char *end) {
return UA_STATUSCODE_BADINTERNALERROR;
id->namespaceIndex = (UA_UInt16)tmp;
}
/* From the current position until the end of the input */
return parse_nodeid_body(id, &input[-2], end);
}
...
...
@@ -149,6 +150,52 @@ UA_NodeId_parse(UA_NodeId *id, const UA_String str) {
UA_StatusCode
res
=
parse_nodeid
(
id
,
(
const
char
*
)
str
.
data
,
(
const
char
*
)
str
.
data
+
str
.
length
);
if
(
res
!=
UA_STATUSCODE_GOOD
)
*
id
=
UA_NODEID_NULL
;
UA_NodeId_clear
(
id
);
return
res
;
}
static
UA_StatusCode
parse_expandednodeid
(
UA_ExpandedNodeId
*
id
,
const
char
*
input
,
const
char
*
end
)
{
*
id
=
UA_EXPANDEDNODEID_NULL
;
/* Reset the NodeId */
const
char
*
pos
=
input
,
*
svr
=
NULL
,
*
svre
=
NULL
,
*
nsu
=
NULL
,
*
ns
=
NULL
,
*
body
=
NULL
;
/*!re2c
("svr=" @svr [0-9]+ @svre ";")?
("ns=" @ns [0-9]+ ";" | "nsu=" @nsu (.\";")* ";")?
@body nodeid_body {
if(svr) {
size_t len = (size_t)((svre) - svr);
if(UA_readNumber((const UA_Byte*)svr, len, &id->serverIndex) != len)
return UA_STATUSCODE_BADINTERNALERROR;
}
if(nsu) {
size_t len = (size_t)((body-1) - nsu);
UA_String nsuri;
nsuri.data = (UA_Byte*)(uintptr_t)nsu;
nsuri.length = len;
UA_StatusCode res = UA_String_copy(&nsuri, &id->namespaceUri);
if(res != UA_STATUSCODE_GOOD)
return res;
} else if(ns) {
UA_UInt32 tmp;
size_t len = (size_t)((body-1) - ns);
if(UA_readNumber((const UA_Byte*)ns, len, &tmp) != len)
return UA_STATUSCODE_BADINTERNALERROR;
id->nodeId.namespaceIndex = (UA_UInt16)tmp;
}
/* From the current position until the end of the input */
return parse_nodeid_body(&id->nodeId, &input[-2], end);
}
* { error: return UA_STATUSCODE_BADINTERNALERROR; } */
}
UA_StatusCode
UA_ExpandedNodeId_parse
(
UA_ExpandedNodeId
*
id
,
const
UA_String
str
)
{
UA_StatusCode
res
=
parse_expandednodeid
(
id
,
(
const
char
*
)
str
.
data
,
(
const
char
*
)
str
.
data
+
str
.
length
);
if
(
res
!=
UA_STATUSCODE_GOOD
)
UA_ExpandedNodeId_clear
(
id
);
return
res
;
}
This diff is collapsed.
Click to expand it.
tests/check_types_parse.c
View file @
e4c166f6
...
...
@@ -58,6 +58,43 @@ START_TEST(parseNodeIdByteString) {
UA_NodeId_clear
(
&
id
);
}
END_TEST
START_TEST
(
parseExpandedNodeIdInteger
)
{
UA_ExpandedNodeId
id
=
UA_EXPANDEDNODEID
(
"ns=1;i=1337"
);
ck_assert_int_eq
(
id
.
nodeId
.
identifierType
,
UA_NODEIDTYPE_NUMERIC
);
ck_assert_int_eq
(
id
.
nodeId
.
identifier
.
numeric
,
1337
);
ck_assert_int_eq
(
id
.
nodeId
.
namespaceIndex
,
1
);
}
END_TEST
START_TEST
(
parseExpandedNodeIdInteger2
)
{
UA_ExpandedNodeId
id
=
UA_EXPANDEDNODEID
(
"svr=5;ns=1;i=1337"
);
ck_assert_int_eq
(
id
.
nodeId
.
identifierType
,
UA_NODEIDTYPE_NUMERIC
);
ck_assert_int_eq
(
id
.
nodeId
.
identifier
.
numeric
,
1337
);
ck_assert_int_eq
(
id
.
nodeId
.
namespaceIndex
,
1
);
ck_assert_int_eq
(
id
.
serverIndex
,
5
);
}
END_TEST
START_TEST
(
parseExpandedNodeIdIntegerNSU
)
{
UA_ExpandedNodeId
id
=
UA_EXPANDEDNODEID
(
"svr=5;nsu=urn:test:1234;i=1337"
);
ck_assert_int_eq
(
id
.
nodeId
.
identifierType
,
UA_NODEIDTYPE_NUMERIC
);
ck_assert_int_eq
(
id
.
nodeId
.
identifier
.
numeric
,
1337
);
UA_String
nsu
=
UA_STRING
(
"urn:test:1234"
);
ck_assert
(
UA_String_equal
(
&
id
.
namespaceUri
,
&
nsu
));
ck_assert_int_eq
(
id
.
serverIndex
,
5
);
UA_ExpandedNodeId_clear
(
&
id
);
}
END_TEST
START_TEST
(
parseExpandedNodeIdIntegerFailNSU
)
{
UA_ExpandedNodeId
id
=
UA_EXPANDEDNODEID
(
"svr=5;nsu=urn:test:1234;;i=1337"
);
ck_assert_int_eq
(
id
.
nodeId
.
identifierType
,
UA_NODEIDTYPE_NUMERIC
);
ck_assert_int_eq
(
id
.
nodeId
.
identifier
.
numeric
,
0
);
}
END_TEST
START_TEST
(
parseExpandedNodeIdIntegerFailNSU2
)
{
UA_ExpandedNodeId
id
=
UA_EXPANDEDNODEID
(
"svr=5;nsu=urn:test:1234;ns=1;i=1337"
);
ck_assert_int_eq
(
id
.
nodeId
.
identifierType
,
UA_NODEIDTYPE_NUMERIC
);
ck_assert_int_eq
(
id
.
nodeId
.
identifier
.
numeric
,
0
);
}
END_TEST
int
main
(
void
)
{
Suite
*
s
=
suite_create
(
"Test Builtin Type Parsing"
);
TCase
*
tc
=
tcase_create
(
"test cases"
);
...
...
@@ -68,6 +105,11 @@ int main(void) {
tcase_add_test
(
tc
,
parseNodeIdGuid
);
tcase_add_test
(
tc
,
parseNodeIdGuidFail
);
tcase_add_test
(
tc
,
parseNodeIdByteString
);
tcase_add_test
(
tc
,
parseExpandedNodeIdInteger
);
tcase_add_test
(
tc
,
parseExpandedNodeIdInteger2
);
tcase_add_test
(
tc
,
parseExpandedNodeIdIntegerNSU
);
tcase_add_test
(
tc
,
parseExpandedNodeIdIntegerFailNSU
);
tcase_add_test
(
tc
,
parseExpandedNodeIdIntegerFailNSU2
);
suite_add_tcase
(
s
,
tc
);
SRunner
*
sr
=
srunner_create
(
s
);
...
...
This diff is collapsed.
Click to expand it.
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
Menu
Projects
Groups
Snippets
Help