Skip to content

Commit

Permalink
Merge pull request #1664 from FIWARE/issue/1647
Browse files Browse the repository at this point in the history
Fixed issue #1621
  • Loading branch information
kzangeli authored Sep 6, 2024
2 parents beba3bd + 8686b55 commit e8b09d6
Show file tree
Hide file tree
Showing 3 changed files with 188 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGES_NEXT_RELEASE
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
## Fixed Issues:
#1621: URL-Encoding single quote in attribute values in TRoE DB

## New Features:
* Distributed subscriptions: subordinate subscriptions are DELETED when their "father" is deleted.
Expand Down
72 changes: 71 additions & 1 deletion src/lib/orionld/troe/pgAttributeBuild.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
*
* Author: Ken Zangelin
*/
#include <string.h> // strlen, strcspn

extern "C"
{
#include "kjson/KjNode.h" // KjNode
Expand All @@ -41,6 +43,68 @@ extern "C"



// ----------------------------------------------------------------------------
//
// kjStringValueEncode -
//
static char* urlencode(const char* s, int sLen, int acceptedLen)
{
int maxLen = (sLen - acceptedLen) * 3 + acceptedLen + 1;
char* sOut = kaAlloc(&orionldState.kalloc, maxLen);

if (sOut == NULL)
return (char*) "too long string value";

int sIx = acceptedLen;
int sOutIx = acceptedLen;

strncpy(sOut, s, acceptedLen);

while (s[sIx] != 0)
{
if (s[sIx] == '\'')
{
sOut[sOutIx++] = '%';
sOut[sOutIx++] = '2';
sOut[sOutIx++] = '7';
}
else
sOut[sOutIx++] = s[sIx];

++sIx;
}

return sOut;
}



// ----------------------------------------------------------------------------
//
// kjStringValueEncode -
//
void kjStringValueEncode(KjNode* nodeP)
{
if (nodeP->type == KjString)
{
size_t len = strlen(nodeP->value.s);
size_t acceptedLen = strcspn(nodeP->value.s, "\'");

if (acceptedLen != len)
nodeP->value.s = urlencode(nodeP->value.s, len, acceptedLen);
}
else if ((nodeP->type == KjObject) || (nodeP->type == KjArray))
{
for (KjNode* nP = nodeP->value.firstChildP; nP != NULL; nP = nP->next)
{
if ((nodeP->type == KjObject) || (nodeP->type == KjArray) || (nodeP->type == KjString))
kjStringValueEncode(nP);
}
}
}



// ----------------------------------------------------------------------------
//
// pgAttributeBuild -
Expand Down Expand Up @@ -82,7 +146,13 @@ bool pgAttributeBuild
else if (strcmp(nodeP->name, "unitCode") == 0) unitCode = nodeP->value.s;
else if (strcmp(nodeP->name, "type") == 0) type = nodeP->value.s;
else if (strcmp(nodeP->name, "datasetId") == 0) datasetId = nodeP->value.s;
else if (strcmp(nodeP->name, "value") == 0) valueNodeP = nodeP;
else if (strcmp(nodeP->name, "value") == 0)
{
if ((nodeP->type == KjObject) || (nodeP->type == KjArray) || (nodeP->type == KjString))
kjStringValueEncode(nodeP);

valueNodeP = nodeP;
}
else if (strcmp(nodeP->name, "json") == 0) valueNodeP = nodeP;
else if (strcmp(nodeP->name, "object") == 0)
{
Expand Down
116 changes: 116 additions & 0 deletions test/functionalTest/cases/0000_troe/troe_urlencode_attr_value.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# Copyright 2024 FIWARE Foundation e.V.
#
# This file is part of Orion-LD Context Broker.
#
# Orion-LD Context Broker is free software: you can redistribute it and/or
# modify it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# Orion-LD Context Broker is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
# General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with Orion-LD Context Broker. If not, see http://www.gnu.org/licenses/.
#
# For those usages not covered by this license please contact with
# orionld at fiware dot org

# VALGRIND_READY - to mark the test ready for valgrindTestSuite.sh

--NAME--
Attribute with strange chars in attribute value

--SHELL-INIT--
export BROKER=orionld
dbInit CB
pgInit $CB_DB_NAME
orionldStart CB -experimental -troe

--SHELL--

#
# 01. Create an entity E1 with an attribute P1 with a string value with 'strange' characters
# 02. See all entities in TRoE DB
# 03. See all attributes in TRoE DB
# 04. See all sub-attributes in TRoE DB - there aren't any
#

echo "01. Create an entity E1 with an attribute P1 with a string value with 'strange' characters"
echo "=========================================================================================="
payload='{
"id": "urn:ngsi-ld:entity:E1",
"type": "Device",
"P1": "'\'0\''",
"P2": {
"value": {
"a": "1"
}
},
"P3": {
"value": {
"a": "'\'2\''"
}
}
}'
orionCurl --url /ngsi-ld/v1/entities --payload "$payload"
echo
echo


echo "02. See all entities in TRoE DB"
echo "==============================="
postgresCmd -sql "SELECT opMode,id,type,ts FROM entities"
echo
echo


echo "03. See all attributes in TRoE DB"
echo "================================="
postgresCmd -sql "SELECT opMode,id,valueType,entityId,subProperties,unitcode,datasetid,text,number,boolean,compound,observedAt,ts FROM attributes"
echo
echo


echo "04. See all sub-attributes in TRoE DB - there aren't any"
echo "========================================================"
postgresCmd -sql "SELECT id,valueType,entityId,attrInstanceId,unitcode,text,number,boolean FROM subAttributes"
echo
echo


--REGEXPECT--
01. Create an entity E1 with an attribute P1 with a string value with 'strange' characters
==========================================================================================
HTTP/1.1 201 Created
Content-Length: 0
Date: REGEX(.*)
Location: /ngsi-ld/v1/entities/urn:ngsi-ld:entity:E1



02. See all entities in TRoE DB
===============================
opmode,id,type,ts
Create,urn:ngsi-ld:entity:E1,https://uri.etsi.org/ngsi-ld/default-context/Device,202REGEX(.*)


03. See all attributes in TRoE DB
=================================
opmode,id,valuetype,entityid,subproperties,unitcode,datasetid,text,number,boolean,compound,observedat,ts
Create,https://uri.etsi.org/ngsi-ld/default-context/P1,String,urn:ngsi-ld:entity:E1,f,,None,%270%27,,,,,202REGEX(.*)
Create,https://uri.etsi.org/ngsi-ld/default-context/P2,Compound,urn:ngsi-ld:entity:E1,f,,None,,,,"{""a"": ""1""}",,202REGEX(.*)
Create,https://uri.etsi.org/ngsi-ld/default-context/P3,Compound,urn:ngsi-ld:entity:E1,f,,None,,,,"{""a"": ""%272%27""}",,202REGEX(.*)


04. See all sub-attributes in TRoE DB - there aren't any
========================================================
id,valuetype,entityid,attrinstanceid,unitcode,text,number,boolean


--TEARDOWN--
brokerStop CB
dbDrop CB
pgDrop $CB_DB_NAME

0 comments on commit e8b09d6

Please sign in to comment.