refactor(core): Update RelativePath browsing for the new QualifiedName format

This commit is contained in:
Julius Pfrommer 2024-12-31 13:04:54 +01:00 committed by Julius Pfrommer
parent 12a3e5c915
commit 83ad60c103
3 changed files with 38 additions and 46 deletions

View File

@ -693,30 +693,24 @@ relativepath_addelem(UA_RelativePath *rp, UA_RelativePathElement *el) {
return UA_STATUSCODE_GOOD;
}
/* Parse name string with '&' as the escape character */
/* Parse name string with '&' as the escape character. Omit trailing &. Allow
* escaped characters in the middle. If the passed re2c lexing, then they are
* delimiters between escaped strings. */
static UA_StatusCode
parse_qn_name(UA_String *name, const char *pos,
const char *end, Escaping esc) {
/* There must be no unescaped characters (also trailing &) */
char *end_esc = find_unescaped((char *)(uintptr_t)pos, end,
(esc == ESCAPING_AND_EXTENDED));
if(end_esc != end)
return UA_STATUSCODE_BADDECODINGERROR;
size_t maxlen = (size_t)(end_esc - pos);
if(maxlen == 0)
return UA_STATUSCODE_GOOD;
const char *end, Escaping esc) {
/* Copy string */
char *namestr = (char*)UA_malloc(maxlen);
if(!namestr)
return UA_STATUSCODE_BADOUTOFMEMORY;
memcpy(namestr, pos, maxlen);
UA_String tmp = {(size_t)(end - pos), (UA_Byte*)(uintptr_t)pos};
UA_StatusCode res = UA_String_copy(&tmp, name);
if(res != UA_STATUSCODE_GOOD)
return res;
/* Unescape in-situ */
char *name_end = unescape(namestr, namestr + maxlen);
name->data = (UA_Byte*)namestr;
name->length = (size_t)(name_end - namestr);
char *esc_end =
unescape((char*)name->data, (const char*)name->data + name->length);
name->length = (size_t)(esc_end - (char*)name->data);
if(name->length == 0)
UA_String_clear(name);
return UA_STATUSCODE_GOOD;
}
@ -843,10 +837,8 @@ yy51:
nsUri.data = (UA_Byte*)(uintptr_t)begin;
if(nsMapping)
res = UA_NamespaceMapping_uri2Index(nsMapping, nsUri, &qn->namespaceIndex);
if(res != UA_STATUSCODE_GOOD) {
UA_String total = {(size_t)(end - begin), (UA_Byte*)(uintptr_t)begin};
return UA_String_copy(&total, &qn->name);
}
if(res != UA_STATUSCODE_GOOD)
return parse_qn_name(&qn->name, begin, end, esc); /* Use the full string for the name */
match_name:
return parse_qn_name(&qn->name, pos, end, esc);

View File

@ -303,30 +303,24 @@ relativepath_addelem(UA_RelativePath *rp, UA_RelativePathElement *el) {
return UA_STATUSCODE_GOOD;
}
/* Parse name string with '&' as the escape character */
/* Parse name string with '&' as the escape character. Omit trailing &. Allow
* escaped characters in the middle. If the passed re2c lexing, then they are
* delimiters between escaped strings. */
static UA_StatusCode
parse_qn_name(UA_String *name, const char *pos,
const char *end, Escaping esc) {
/* There must be no unescaped characters (also trailing &) */
char *end_esc = find_unescaped((char *)(uintptr_t)pos, end,
(esc == ESCAPING_AND_EXTENDED));
if(end_esc != end)
return UA_STATUSCODE_BADDECODINGERROR;
size_t maxlen = (size_t)(end_esc - pos);
if(maxlen == 0)
return UA_STATUSCODE_GOOD;
const char *end, Escaping esc) {
/* Copy string */
char *namestr = (char*)UA_malloc(maxlen);
if(!namestr)
return UA_STATUSCODE_BADOUTOFMEMORY;
memcpy(namestr, pos, maxlen);
UA_String tmp = {(size_t)(end - pos), (UA_Byte*)(uintptr_t)pos};
UA_StatusCode res = UA_String_copy(&tmp, name);
if(res != UA_STATUSCODE_GOOD)
return res;
/* Unescape in-situ */
char *name_end = unescape(namestr, namestr + maxlen);
name->data = (UA_Byte*)namestr;
name->length = (size_t)(name_end - namestr);
char *esc_end =
unescape((char*)name->data, (const char*)name->data + name->length);
name->length = (size_t)(esc_end - (char*)name->data);
if(name->length == 0)
UA_String_clear(name);
return UA_STATUSCODE_GOOD;
}
@ -361,10 +355,8 @@ parse_qn(UA_QualifiedName *qn, const char *pos, const char *end,
nsUri.data = (UA_Byte*)(uintptr_t)begin;
if(nsMapping)
res = UA_NamespaceMapping_uri2Index(nsMapping, nsUri, &qn->namespaceIndex);
if(res != UA_STATUSCODE_GOOD) {
UA_String total = {(size_t)(end - begin), (UA_Byte*)(uintptr_t)begin};
return UA_String_copy(&total, &qn->name);
}
if(res != UA_STATUSCODE_GOOD)
return parse_qn_name(&qn->name, begin, end, esc); /* Use the full string for the name */
match_name:
return parse_qn_name(&qn->name, pos, end, esc);

View File

@ -28,6 +28,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
const UA_String input = {size, (UA_Byte *) (void *) data};
UA_String out = UA_STRING_NULL;
UA_String out2 = UA_STRING_NULL;
UA_AttributeOperand ao;
UA_AttributeOperand ao2;
@ -46,10 +47,17 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
goto cleanup;
UA_assert(ret == UA_STATUSCODE_GOOD);
ret = UA_AttributeOperand_print(&ao2, &out2);
if(ret == UA_STATUSCODE_BADOUTOFMEMORY)
goto cleanup;
UA_assert(ret == UA_STATUSCODE_GOOD);
UA_assert(UA_String_equal(&out, &out2));
UA_assert(UA_equal(&ao, &ao2, &UA_TYPES[UA_TYPES_ATTRIBUTEOPERAND]));
cleanup:
UA_String_clear(&out);
UA_String_clear(&out2);
UA_AttributeOperand_clear(&ao);
UA_AttributeOperand_clear(&ao2);
return 0;