Is + a disallowed charecter in URLs? - codeigniter

What is disallowed in the following URL?
http://myPortfolio/Showcase/Kimber+Tisdale+Photography
I am getting The URI you submitted has disallowed characters. error message. Where as as far as I understand + is allowed, isn't it?
Reference: Which characters make a URL invalid?

It is an allowed character but not in the way you are using it. It is allowed in the query string part of a url, not in the url path names.
If you are just seperating words, it is more usual to use a hyphen or an underscore, or %20 for a space. You can use CI's url helper to encode strings for you:
$title = 'Kimber Tisdale Photography';
$url_title = url_title($title, '-');
// ouptut kimber-tisdale-photography
http://www.codeigniter.com/user_guide/helpers/url_helper.html#url_title

The + is allowed in URI paths.
You can check it yourself:
Visit the URI standard.
Check which characters are allowed in the Path component.
Note that every non-empty path may contain characters from the segment set.
Note that the segment set consists of characters from the pchar set.
Note that the pchar set contains characters from the sub-delims set.
And sub-delims is defined to consist of:
"!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
As you can see, the + is listed here.
(See my list of all allowed characters in URI paths.)
A prominent example of + in the path of HTTP(S) URIs are Google Plus profiles, e.g.:
https://plus.google.com/+MattCutts

Related

Go: how to not remove double quotes on cookies

Go removes double quotes in cookies. Is there a way to keep double quotes in cookies in Go?
For example, I'm sending a small JSON message and "SetCookie" strips double quote.
w.SetCookie("my_cookie_name", small_json_message)
More about Cookies:
The HTTP RFC defines quoted string values. See https://www.rfc-editor.org/rfc/rfc7230#section-3.2.6
The proposed cookie RFC explicitly says double quotes are allowed in cookie values: cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE )
Go currently has a condition to insert double quote into cookies, so obviously double quotes are allowed.
; is the cookie delimiter.
Values with ASCII characters outside the limited ASCII range may be quoted (The RFC calls this the quoted_string) which expands the allowed character set.
JSON does not contain the ; character, so for ; to appear in JSON it can only appear in string values. In JSON, string values are already quoted.
I've confirmed testing using a simple k:v JSON payload and it works fine on all major browsers with no issues.
Cookies are typically generated by server data, not user data. This means well structured, not arbitrary, JSON may be used
JSON easily can conform to the cookie RFC. Additionally, even though it's not an issue with this example of JSON, regarding the hypothetical concern of not conforming to the RFC:
A cookie is transmitted as a HTTP headers. Many HTTP headers commonly disregard the RFC. For example, the Sec-Ch-Ua header created by Chrome, includes several "bad" characters.
Sec-Ch-Ua: "Chromium";v="92", " Not A;Brand";v="99", "Google Chrome";v="92"
"comma" is "disallowed" and it's used all the time.
Even if double quotes were "wrong", which they are not, but if they were, there are lots of in-the-wild examples of cookies containing quotes.
For reference, here's the relevant section of RFC 6265
set-cookie-header = "Set-Cookie:" SP set-cookie-string
set-cookie-string = cookie-pair *( ";" SP cookie-av )
cookie-pair = cookie-name "=" cookie-value
cookie-name = token
cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE )
cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E
; US-ASCII characters excluding CTLs,
; whitespace DQUOTE, comma, semicolon,
; and backslash
Where one can see whitespace DQUOTE is disallowed and DQUOTE is allowed.
HTTP cookies are allowed to have double quotes.
Are you sure? rfc6265 states:
set-cookie-header = "Set-Cookie:" SP set-cookie-string
set-cookie-string = cookie-pair *( ";" SP cookie-av )
cookie-pair = cookie-name "=" cookie-value
cookie-name = token
cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE )
cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E
; US-ASCII characters excluding CTLs,
; whitespace DQUOTE, comma, semicolon,
; and backslash
So it appears that Go is following the specification (the spec previously definesDQUOTE to mean double quote).
See this issue for further information.
Yes. Double quotes are allowed in cookies and other HTTP headers. Double quotes are also used to escape characters that would be otherwise invalid.
Here's a way to manually set a cookie, where w is the http.responseWriter and b is the bytes of the cookie. Max-Age is in seconds and 999999999 is ~31.69 years.
w.Header().Set("Set-Cookie", "your_cookie_name="+string(b)+"; Path=/; Domain=localhost; Secure; Max-Age=999999999; SameSite=Strict")
Since you'll probably use cURL to test sending cookies to the server, here's a useful test:
curl --insecure --cookie 'test1={"test1":"v1"}; test2={"test2":"v2"}' https://localhost:8081/
Which results in a HTTP header like the following:
GET / HTTP/2.0
Host: localhost:8081
Accept: */*
Cookie: test1={"test1":"v1"}; test2={"test2":"v2"}
User-Agent: curl/7.0.0
Also note, many of the RFC rules are ignored all the time, especially commas. For example, Chrome sets this header:
Sec-Ch-Ua: "Google Chrome";v="107", "Chromium";v="107", "Not=A?Brand";v="24"
Gasp! Is uses commas and other things! It is well established that commas in HTTP headers are okay, even though the RFC appears to say otherwise.
Note that the Chrome header uses spaces, many double quotes, commas, special characters, and semi colon. Chrome here uses double quotes around many values needing escaping, and that's the right way to be compliant with the RFC.
Note that the cookie RFC 6265 is a proposal and has been for 11 years. There are reasons for that. Knowing that cookies are just a HTTP header, look at the accepted HTTP RFC for quoted string semantic for header values:
HTTP RFC 7230 3.2.6.
These characters are included for quoted-string:
HTAB, SP
!#$%&'()*+,-./0123456789:;<=>?#ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~
%x80-FF
The characters " and / may be included if escaped.

Removing/Replacing reserved or invalid url characters in a string

I'm in the process of creating sef urls for my app. I just encountered an error where one of my objects contains the following characters:
##!*
My desired output is the following where anything illegal outside of reserved/unreserved will get replaced by an underscore:
#_!*
I planned on using this regular expression to filter the bad characters:
[^]A-Za-z0-9_.~!*''();:#&=+$,/?#[%-]+
And do the replacement via gsub
'##!*'.gsub!(/[^]_.~!*''();:#&=+$,/?#[%-]+/, '_')
But not getting anything returned at all. What's going on here?
'<##_!*>'.gsub(/[\[\]^A-Za-z0-9.~!*''();:#&=+$,\/?#%+-]/, '_')
#=> "<_____>"
'[', ']' and '/' must be escaped, '-' must be at the beginning or end of the character class and '^' cannot be at the beginning of the character class (the character class being denoted by the outer '[' and ']' characters). There's no point in replacing '' with '' so I've not included that character in the character class.
Do you wish to also replace '<' and '>'? Are you sure letters and digits "reserved characters"?

How to replace the last "/" with a dash in a URL

I have this URL in a Sinatra-based application:
<li><a href="/blog/<%= blog.title.tr(' ', '-') %>/<%= blog.slug %>"
method="get">Show</a></li>
When I click on it, the URL looks like this:
http://127.0.0.1:9292/blog/A-lovely-day/654790
I am trying to make the last / also a - too, so it will be:
http://127.0.0.1:9292/blog/A-lovely-day-654790
How do I replace it after the URL has been rendered?
Given that you started with:
The slash is not part of the title, but simply the character in red. Replace it with - in the code:
You can specify more than one character to transform
blog.title.tr(" /", "-")
r = /
.* # match any character zero or more times (greedily)
\K # forget all matches so far
\/ # match a forward slash
/x # free-spacing regex definition mode
To return a new string with the replacement:
blog.title.sub(r, '-')
To make the replacement in the existing string:
blog.title.sub!(r, '-')
One could use capture groups in place of \K:
blog.title.sub(/(.*)\/(.*)/, '\1-\2')
Another way to make the replacement in the existing string:
blog.title[blog.title.rindex('/')] = '-'
Here's how I'd go about this:
require 'uri'
title = 'A lovely day'
slug = '654790'
uri = URI.parse('http://127.0.0.1:9292/blog/')
[*title.split, slug].join('-') # => "A-lovely-day-654790"
uri.path += [*title.split, slug].join('-')
uri.to_s # => "http://127.0.0.1:9292/blog/A-lovely-day-654790"
Generate the URL in the controller and only output the variable in the view.
It's always good to use the built-in tools. URI helps when manipulating URLs/URIs, and understands appropriate encoding if necessary.
Also, it's useful to remember that the path is actually a file pathname, so sometimes the File package can be very useful for manipulating/splitting/joining. This wasn't a good example, but it's come in very handy.
'http://127.0.0.1:9292/blog/A-lovely-day/654790'.
sub(/\/(?!.*\/)/,'-') # match a / that is not followed by another /
#=> "http://127.0.0.1:9292/blog/A-lovely-day-654790"

PregMatch . space and #?

Can someone tell me, what's wrong in this code:
if ((!preg_match("[a-zA-Z0-9 \.\s]", $username)) || (!preg_match("[a-zA-Z0-9 \.\s]", $password)));
exit("result_message=Error: invalid characters");
}
??
Several things are wrong. I assume that the code you are looking for is:
if (preg_match('~[^a-z0-9\h.]~i', $username) || preg_match('~[^a-z0-9\h.]~i', $password))
exit('result_message=Error: invalid characters');
What is wrong in your code?
the pattern [a-zA-Z0-9 \.\s] is false for multiple reasons:
a regex pattern in PHP must by enclosed by delimiters, the most used is /, but as you can see, I have choosen ~. Example: /[a-zA-Z \.\s]/
the character class is strange because it contains a space and the character class \s that contains the space too. IMO, to check a username or a password, you only need the space and why not the tab, but not the carriage return or the line feed character! You can remove \s and let the space, or you can use the \h character class that matches all horizontal white spaces. /[a-zA-Z\h\.]/ (if you don't want to allow tabs, replace the \h by a space)
the dot has no special meaning inside a character class and doesn't need to be escaped: /[a-zA-Z\h.]/
you are trying to verify a whole string, but your pattern matches a single character! In other words, the pattern checks only if the string contains at least an alnum, a space or a dot. If you want to check all the string you must use a quantifier + and anchors for the start ^ and the end $ of the string. Example ∕^[a-zA-Z0-9\h.]+$/
in fine, you can shorten the character class by using the case-insensitive modifier i: /^[a-z0-9\h.]+$/i
But there is a faster way, instead of negate with ! your preg_match assertion and test if all characters are in the character range you want, you can only test if there is one character you don't want in the string. To do this you only need to negate the character class by inserting a ^ at the first place:
preg_match('/[^a-z0-9\h.]/i', ...
(Note that the ^ has a different meaning inside and outside a character class. If ^ isn't at the begining of a character class, it is a simple literal character.)

VisualStudio - How to escape this chars

I think i need to escape the special chars here:
Process.Start(userSelectedFilePath, "\u0007" & ThisDir.Path & "\u000B" & checkedpath1 & "\u0007")
The result need to be like: userselecfilepath "a blackquoted path\and other folder"
what i'm doing wrong?
thankyou
UPDATE
Solution:
ControlChars.Quote & Path.Combine(ThisDir.Path, checkedpath1) & ControlChars.Quote
Process.Start(userSelectedFilePath, Path.Combine(ThisDir.Path, checkedpath));
Path.Combine
If path1 is not a drive reference (that is, "C:" or "D:") and does not
end with a valid separator character as defined in
DirectorySeparatorChar, AltDirectorySeparatorChar, or
VolumeSeparatorChar, DirectorySeparatorChar is appended to path1
before concatenation.
If path2 does not include a root (for example, if path2 does not start
with a separator character or a drive specification), the result is a
concatenation of the two paths, with an intervening separator
character. If path2 includes a root, path2 is returned.
The parameters are not parsed if they have white space. Therefore, if
path2 includes white space (for example, " c:\ "), the Combine method
appends path2 to path1 instead of returning only path2.
Not all invalid characters for directory and file names are
interpreted as unacceptable by the Combine method, because you can use
these characters for search wildcard characters. For example, while
Path.Combine("c:\", "*.txt") might be invalid if you were to create a
file from it, it is valid as a search string. It is therefore
successfully interpreted by the Combine method.
try this:
Process.Start(userSelectedFilePath, "\\" & ThisDir.Path & "\\" & checkedpath1 & "\\")

Resources