mirror of
https://github.com/stashapp/stash.git
synced 2025-12-18 21:04:37 +03:00
Fix URL encoding again (#3044)
Co-authored-by: WithoutPants <53250216+WithoutPants@users.noreply.github.com>
This commit is contained in:
@@ -145,18 +145,69 @@ export class ListFilterModel {
|
|||||||
jsonParameters = [params.c!];
|
jsonParameters = [params.c!];
|
||||||
}
|
}
|
||||||
params.c = jsonParameters.map((jsonString) => {
|
params.c = jsonParameters.map((jsonString) => {
|
||||||
let decodedJson = jsonString;
|
const decoding = true;
|
||||||
// replace () back to {}
|
return ListFilterModel.translateSpecialCharacters(
|
||||||
decodedJson = decodedJson.replaceAll("(", "{");
|
decodeURIComponent(jsonString),
|
||||||
decodedJson = decodedJson.replaceAll(")", "}");
|
decoding
|
||||||
// decode all other characters
|
);
|
||||||
decodedJson = decodeURIComponent(decodedJson);
|
|
||||||
return decodedJson;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static translateSpecialCharacters(input: string, decoding: boolean) {
|
||||||
|
let inString = false;
|
||||||
|
let escape = false;
|
||||||
|
return [...input]
|
||||||
|
.map((c) => {
|
||||||
|
if (escape) {
|
||||||
|
// this character has been escaped, skip
|
||||||
|
escape = false;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (c) {
|
||||||
|
case "\\":
|
||||||
|
// escape the next character if in a string
|
||||||
|
if (inString) {
|
||||||
|
escape = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '"':
|
||||||
|
// unescaped quote, toggle inString
|
||||||
|
inString = !inString;
|
||||||
|
break;
|
||||||
|
case "(":
|
||||||
|
// decode only: restore ( to { if not in a string
|
||||||
|
if (decoding && !inString) {
|
||||||
|
return "{";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ")":
|
||||||
|
// decode only: restore ) to } if not in a string
|
||||||
|
if (decoding && !inString) {
|
||||||
|
return "}";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "{":
|
||||||
|
// encode only: replace { with ( if not in a string
|
||||||
|
if (!decoding && !inString) {
|
||||||
|
return "(";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "}":
|
||||||
|
// encode only: replace } with ) if not in a string
|
||||||
|
if (!decoding && !inString) {
|
||||||
|
return ")";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
})
|
||||||
|
.join("");
|
||||||
|
}
|
||||||
|
|
||||||
public configureFromQueryString(query: string) {
|
public configureFromQueryString(query: string) {
|
||||||
const parsed = queryString.parse(query, { decode: false });
|
const parsed = queryString.parse(query, { decode: false });
|
||||||
const decoded = ListFilterModel.decodeQueryParameters(parsed);
|
const decoded = ListFilterModel.decodeQueryParameters(parsed);
|
||||||
@@ -192,15 +243,15 @@ export class ListFilterModel {
|
|||||||
// Returns query parameters with necessary parts encoded
|
// Returns query parameters with necessary parts encoded
|
||||||
public getQueryParameters(): IQueryParameters {
|
public getQueryParameters(): IQueryParameters {
|
||||||
const encodedCriteria: string[] = this.criteria.map((criterion) => {
|
const encodedCriteria: string[] = this.criteria.map((criterion) => {
|
||||||
let str = criterion.toJSON();
|
const decoding = false;
|
||||||
|
let str = ListFilterModel.translateSpecialCharacters(
|
||||||
|
criterion.toJSON(),
|
||||||
|
decoding
|
||||||
|
);
|
||||||
|
|
||||||
// URL-encode other characters
|
// URL-encode other characters
|
||||||
str = encodeURI(str);
|
str = encodeURI(str);
|
||||||
// force URL-encode existing ()
|
|
||||||
str = str.replaceAll("(", "%28");
|
|
||||||
str = str.replaceAll(")", "%29");
|
|
||||||
// replace JSON '{'(%7B) '}'(%7D) with explicitly unreserved ()
|
|
||||||
str = str.replaceAll("%7B", "(");
|
|
||||||
str = str.replaceAll("%7D", ")");
|
|
||||||
// only the reserved characters ?#&;=+ need to be URL-encoded
|
// only the reserved characters ?#&;=+ need to be URL-encoded
|
||||||
// as they have special meaning in query strings
|
// as they have special meaning in query strings
|
||||||
str = str.replaceAll("?", encodeURIComponent("?"));
|
str = str.replaceAll("?", encodeURIComponent("?"));
|
||||||
@@ -209,6 +260,7 @@ export class ListFilterModel {
|
|||||||
str = str.replaceAll(";", encodeURIComponent(";"));
|
str = str.replaceAll(";", encodeURIComponent(";"));
|
||||||
str = str.replaceAll("=", encodeURIComponent("="));
|
str = str.replaceAll("=", encodeURIComponent("="));
|
||||||
str = str.replaceAll("+", encodeURIComponent("+"));
|
str = str.replaceAll("+", encodeURIComponent("+"));
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user