Skip to content

Commit 1e429f4

Browse files
Merge pull request #50 from contentstack/development
Development
2 parents 625fbb5 + 3adc068 commit 1e429f4

9 files changed

Lines changed: 47 additions & 35 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# CHANGELOG
22

3+
### **APR-14-2025**
4+
5+
#### v1.0.1 - SRE fixes
6+
#### workflow fix
7+
38
### **FEB-17-2025**
49

510
#### v1.0.0 - v3 migration null support added

lib/contentstack.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ export 'src/asset.dart';
88
export 'src/contenttype.dart';
99
export 'src/contenttype_query.dart';
1010
export 'src/entry.dart';
11+
export 'src/enums/include.dart';
12+
export 'src/enums/include_type.dart';
1113
export 'src/error/error.dart';
1214
export 'src/image_transform.dart';
1315
export 'src/models/assetmodel.dart';

lib/src/base_query.dart

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,8 @@ class BaseQuery {
156156
}
157157

158158
void where(String fieldUid, QueryOperation queryOperation) {
159-
if (fieldUid.isNotEmpty) {
160-
switch(queryOperation.operationType) {
159+
if(_isValidFieldUid(fieldUid)) {
160+
switch (queryOperation.operationType) {
161161
case QueryOperationType.Equals:
162162
parameter[fieldUid] = queryOperation.value;
163163
break;
@@ -191,4 +191,10 @@ class BaseQuery {
191191
}
192192
}
193193
}
194+
195+
bool _isValidFieldUid(String fieldUid) {
196+
final validFieldUidPattern = RegExp(r'^[a-zA-Z0-9-_.]+$');
197+
return validFieldUidPattern.hasMatch(fieldUid);
198+
}
199+
194200
}

lib/src/entry_queryable.dart

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// ignore_for_file: lines_longer_than_80_chars
1+
// ignore_for_file: lines_longer_than_80_chars, unnecessary_lambdas
22

33
import 'package:contentstack/constant.dart';
44
import 'package:contentstack/src/enums/include.dart';
@@ -8,6 +8,11 @@ import 'package:contentstack/src/enums/include_type.dart';
88
class EntryQueryable {
99
Map<String, Object?> parameter = <String, Object?>{};
1010

11+
//sanitize
12+
String sanitizeInput(String input) {
13+
return input.replaceAll(RegExp(r'[^a-zA-Z0-9-_.]'), '');
14+
}
15+
1116
///
1217
/// This method adds key and value to an Entry.
1318
/// [key] The key as string which needs to be added to an Entry
@@ -43,10 +48,7 @@ class EntryQueryable {
4348
///
4449
void except(List<String> fieldUid) {
4550
if (fieldUid.isNotEmpty) {
46-
final List referenceArray = [];
47-
for (final item in fieldUid) {
48-
referenceArray.add(item);
49-
}
51+
final List<String> referenceArray = fieldUid.map((item) => sanitizeInput(item)).toList();
5052
parameter['except[BASE][]'] = referenceArray.toString();
5153
}
5254
}
@@ -171,15 +173,15 @@ class EntryQueryable {
171173
case IncludeType.None:
172174
if (referenceFieldUid.runtimeType == List) {
173175
for (var uid in referenceFieldUid) {
174-
referenceArray.add(uid);
176+
referenceArray.add(sanitizeInput(uid));
175177
}
176178
} else if (referenceFieldUid.runtimeType == String) {
177-
referenceArray.add(referenceFieldUid);
179+
referenceArray.add(sanitizeInput(referenceFieldUid));
178180
}
179181

180182
if (includeReferenceField.fieldUidList.isNotEmpty) {
181183
for (final item in includeReferenceField.fieldUidList) {
182-
referenceArray.add(item);
184+
referenceArray.add(sanitizeInput(item));
183185
}
184186
}
185187
parameter['include[]'] = referenceArray.toString();
@@ -188,7 +190,7 @@ class EntryQueryable {
188190
final Map<String, dynamic> referenceOnlyParam = <String, dynamic>{};
189191
if (includeReferenceField.fieldUidList.isNotEmpty) {
190192
for (final item in includeReferenceField.fieldUidList) {
191-
referenceArray.add(item);
193+
referenceArray.add(sanitizeInput(item));
192194
}
193195
}
194196
referenceOnlyParam[referenceFieldUid] = referenceArray;
@@ -199,7 +201,7 @@ class EntryQueryable {
199201
final Map<String, dynamic> referenceOnlyParam = <String, dynamic>{};
200202
if (includeReferenceField.fieldUidList.isNotEmpty) {
201203
for (final item in includeReferenceField.fieldUidList) {
202-
referenceArray.add(item);
204+
referenceArray.add(sanitizeInput(item));
203205
}
204206
}
205207
referenceOnlyParam[referenceFieldUid] = referenceArray;
@@ -262,10 +264,7 @@ class EntryQueryable {
262264
///
263265
void only(List<String> fieldUid) {
264266
if (fieldUid.isNotEmpty) {
265-
final List referenceArray = [];
266-
for (final item in fieldUid) {
267-
referenceArray.add(item);
268-
}
267+
final List<String> referenceArray = fieldUid.map((item) => sanitizeInput(item)).toList();
269268
parameter['only[BASE][]'] = referenceArray.toString();
270269
}
271270
}

lib/src/query_params.dart

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ class URLQueryParams {
55
// Appends a parameter to the query with received key.
66
void append(String key, dynamic value) {
77
if (value != null && value.toString().isNotEmpty) {
8-
_values[key] = Uri.encodeQueryComponent(value.toString());
8+
final sanitizedValue = _sanitizeInput(value.toString());
9+
_values[key] = Uri.encodeQueryComponent(sanitizedValue);
910
}
1011
}
1112

@@ -18,20 +19,22 @@ class URLQueryParams {
1819
// * param1=value1&param2=value2
1920
@override
2021
String toString() {
21-
String response = '';
22-
_values.forEach((key, value) {
23-
response += '$key=$value&';
24-
});
25-
return response.substring(0, response.isEmpty ? 0 : response.length - 1);
22+
return _values.entries
23+
.map((entry) => '${Uri.encodeQueryComponent(entry.key)}=${entry.value}')
24+
.join('&');
2625
}
2726

28-
String toUrl(String urls) {
29-
String updatedUrl;
30-
if (urls.isNotEmpty && urls.endsWith('/')) {
31-
updatedUrl = urls.substring(0, urls.length - 1);
32-
} else {
33-
updatedUrl = urls;
34-
}
35-
return '$updatedUrl?${toString()}';
27+
String toUrl(String url) {
28+
if (url.isEmpty) throw ArgumentError('URL cannot be empty');
29+
30+
final Uri parsedUri = Uri.parse(url);
31+
final String normalizedUrl = parsedUri.normalizePath().toString();
32+
33+
return Uri.parse('$normalizedUrl?${toString()}').toString();
34+
}
35+
36+
String _sanitizeInput(String input) {
37+
final pattern = RegExp(r'[<>\"\;(){}]');
38+
return input.replaceAll(pattern, '');
3639
}
3740
}

lib/src/stack.dart

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -463,8 +463,6 @@ class Stack {
463463
'authorization': headers!['authorization']!,
464464
'api_key': headers!['api_key']!,
465465
};
466-
467-
print('Request URL: $_url');
468466
await http.get(Uri.parse(_url), headers: _headers).then((response) {
469467
final Map bodyJson = json.decode(utf8.decode(response.bodyBytes));
470468
print(bodyJson);

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: contentstack
22
description: Contentstack is a headless CMS with an API-first approach that puts content at the centre.
3-
version: 1.0.0
3+
version: 1.0.1
44
homepage: https://www.contentstack.com
55
documentation: https://www.contentstack.com/docs/developers/apis/content-delivery-api
66

test/query_test.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,6 @@ void main() {
393393
query.operator(QueryOperator(QueryOperatorType.Or, listOfQuery));
394394
await query.find().then((response) {
395395
final completeUrl = query.getQueryUrl()['query'];
396-
//(response.toString());
397396
expect('{\"\$or\":[{\"title\":\"Room 13\"},{\"number\":20}]}',
398397
completeUrl);
399398
}).catchError((onError) {

test/stack_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ void main() {
143143
group('testcase for URLQueryParams', () {
144144
test('test query_params', () {
145145
final params = URLQueryParams()..append('key', 'value');
146-
final url = params.toUrl('cdn.contentstack.io/');
146+
final url = params.toUrl('cdn.contentstack.io');
147147
expect('cdn.contentstack.io?key=value', url);
148148
});
149149

0 commit comments

Comments
 (0)