TouchDB-Android - Help to understand TDServer.pathForName

51 views
Skip to first unread message

bsquared

unread,
Nov 13, 2012, 4:40:41 PM11/13/12
to mobile-c...@googlegroups.com
Hello,

I am trying to figure out this block of code, but it escapes me.
https://github.com/couchbaselabs/TouchDB-Android/blob/master/TouchDB-Android/src/com/couchbase/touchdb/TDServer.java#L67

I am not sure what the regular expression statement is supposed to do.  I ran it through Regex::Explain the output is https://gist.github.com/4068456.
  public static final String LEGAL_CHARACTERS = "abcdefghijklmnopqrstuvwxyz0123456789_$()+-/";
  if((name == null) || (name.length() == 0) || Pattern.matches("^" + LEGAL_CHARACTERS, name) || !Character.isLowerCase(name.charAt(0))) {
            return null;
        }
What value would cause the statement to return true and thus return null from the method?

Additionally, what name scenario would have slashes to replace with colon?
  name = name.replace('/', ':')

If someone could point me in the right direction I would appreciate it. I am considering a desktop version, and
I want to write tests for these statements.

Thank you.

Regards,
Brian


Marty Schoch

unread,
Nov 13, 2012, 5:52:25 PM11/13/12
to mobile-c...@googlegroups.com
The purpose of this block of code is to determine if the database name is valid.

The regular expression works as follows, first we defined a string containing all the legal characters:  

LEGAL_CHARACTERS = "abcdefghijklmnopqrstuvwxyz0123456789_$()+-/";

Then the regular expression is evaluated as:

Pattern.matches("^" + LEGAL_CHARACTERS, name)

By prefixing the LEGAL_CHARACTERS string with "^" we are saying match any character that is NOT LEGAL.  It matches any single character, which is what we want because any database name containing even a single illegal-character is invalid.

The remaining checks are for null, empty string, and also ensuring that the first character is lowercase.

marty






--
 
 

bsquared

unread,
Nov 13, 2012, 7:07:33 PM11/13/12
to mobile-c...@googlegroups.com
Thanks for your response. I am having trouble getting a true result
from the Pattern matches statement.


As a quick test I did this:

private void pathForName(String name) {
if ((name == null) || (name.length() == 0)) {
return;
}

boolean b1 = Pattern.matches("^" + LEGAL_CHARACTERS, name);
System.out.print(String.format(
"Pattern: %s\n Name: %s\n Evaluates as: %s\n",
"^" + LEGAL_CHARACTERS,
name,
Boolean.toString(b1))
);

}

public void testPathForName() {
pathForName("foo"); // expect false
pathForName("FOO"); // expect true?
pathForName("<,."); // expect true
}

The result was this:
Pattern: ^abcdefghijklmnopqrstuvwxyz0123456789_$()+-/
Name: foo
Evaluates as: false
Pattern: ^abcdefghijklmnopqrstuvwxyz0123456789_$()+-/
Name: FOO
Evaluates as: false
Pattern: ^abcdefghijklmnopqrstuvwxyz0123456789_$()+-/
Name: <,.
Evaluates as: false

I expected strings two and three to be invalid, but they all were
evaluated as valid.

Please let me know where I may have erred.

Also, I am curious about the String.replace line where "/" is replaced
with ":". Is this just to generate a valid file name?

Thank you.
--
Regards,
Brian

Marty Schoch

unread,
Nov 13, 2012, 8:34:58 PM11/13/12
to mobile-c...@googlegroups.com
Yeah, it looks like a bug.  Please file an issue on github, or even better, submit a fix if you can work out the proper way to do it.

marty



--
Regards,
Brian

--



bsquared

unread,
Nov 13, 2012, 8:58:45 PM11/13/12
to mobile-c...@googlegroups.com
On 11/13/2012 02:52 PM, Marty Schoch wrote:
> The purpose of this block of code is to determine if the database name is
> valid.
>
> The regular expression works as follows, first we defined a string
> containing all the legal characters:

Valid database name or valid filename?

I worked out valid filename as this.
LEGAL_CHARACTERS = "[^\\w\\d_$/+-]*$";

These characters that are not in the original are also valid filename
characters on android /data file system.
~%^

>
> LEGAL_CHARACTERS = "abcdefghijklmnopqrstuvwxyz0123456789_$()+-/";
>
> Then the regular expression is evaluated as:
>
> Pattern.matches("^" + LEGAL_CHARACTERS, name)
>
> By prefixing the LEGAL_CHARACTERS string with "^" we are saying match any
> character that is NOT LEGAL. It matches any single character, which is
> what we want because any database name containing even a single
> illegal-character is invalid.
>
> The remaining checks are for null, empty string, and also ensuring that the
> first character is lowercase.
>
> marty
>
>
>
>
--
Regards,
Brian

Marty Schoch

unread,
Nov 13, 2012, 9:36:05 PM11/13/12
to mobile-c...@googlegroups.com
For compatibility with CouchDB it is important that we limit valid database names to the original set, even though the file system could support more.

marty


--
Regards,
Brian

--



bsquared

unread,
Nov 13, 2012, 9:38:45 PM11/13/12
to mobile-c...@googlegroups.com
On 11/13/2012 05:34 PM, Marty Schoch wrote:
> Yeah, it looks like a bug. Please file an issue on github, or even better,
> submit a fix if you can work out the proper way to do it.
>
> marty
>
>


Happy to do so.
Bug 81, pull request submitted.


--
Regards,
Brian

bsquared

unread,
Nov 13, 2012, 9:43:28 PM11/13/12
to mobile-c...@googlegroups.com
On Tue, Nov 13, 2012 at 6:36 PM, Marty Schoch <marty....@gmail.com> wrote:
> For compatibility with CouchDB it is important that we limit valid database
> names to the original set, even though the file system could support more.
>
> marty
>
I had to remove parens. They aren't valid on android's /data fs

sh-3.2# touch file_n4-(me)+
sh: syntax error near unexpected token `('

Do they need a replacement ?

I left the front slash as it was replaced later in the block.

--
Regards,
Brian

Marty Schoch

unread,
Nov 13, 2012, 9:45:50 PM11/13/12
to mobile-c...@googlegroups.com
I think parens are valid in a filename, they just have to be escaped in the shell.  I don't feel like booting up an emulator to try it though.

marty



--
Regards,
Brian

--



bsquared

unread,
Nov 13, 2012, 10:25:26 PM11/13/12
to mobile-c...@googlegroups.com
On 11/13/2012 06:45 PM, Marty Schoch wrote:
> I think parens are valid in a filename, they just have to be escaped in the
> shell. I don't feel like booting up an emulator to try it though.
>
> marty
>
>

You are correct. I'll re-submit.
--
Regards,
Brian
Reply all
Reply to author
Forward
0 new messages