Fixed a bug in Luminotes Desktop in which a backslash within a note was duplicated each time the note was saved.
This commit is contained in:
parent
e4104adb81
commit
d37422b592
2
NEWS
2
NEWS
|
@ -3,6 +3,8 @@
|
|||
* Added a "start a new discussion" link to each discussion forum page.
|
||||
* Updated Luminotes Server INSTALL file with instructions for setting the
|
||||
http_url configuration setting.
|
||||
* Fixed a bug in Luminotes Desktop in which a backslash within a note was
|
||||
duplicated each time the note was saved.
|
||||
* Fixed a bug in which special characters in a customer's name prevented
|
||||
PayPal payments from going through properly.
|
||||
|
||||
|
|
|
@ -174,6 +174,15 @@ class Database( object ):
|
|||
except ImportError:
|
||||
return None
|
||||
|
||||
def unescape( self, sql_command ):
|
||||
"""
|
||||
For backends that don't treat backslashes specially, un-double all backslashes in the given
|
||||
sql_command.
|
||||
"""
|
||||
if self.__backend == Persistent.SQLITE_BACKEND:
|
||||
return sql_command.replace( "\\\\", "\\" )
|
||||
return sql_command
|
||||
|
||||
@synchronized
|
||||
def save( self, obj, commit = True ):
|
||||
"""
|
||||
|
@ -187,11 +196,11 @@ class Database( object ):
|
|||
connection = self.get_connection()
|
||||
cursor = connection.cursor()
|
||||
|
||||
cursor.execute( obj.sql_exists() )
|
||||
cursor.execute( self.unescape( obj.sql_exists() ) )
|
||||
if cursor.fetchone():
|
||||
cursor.execute( obj.sql_update() )
|
||||
cursor.execute( self.unescape( obj.sql_update() ) )
|
||||
else:
|
||||
cursor.execute( obj.sql_create() )
|
||||
cursor.execute( self.unescape( obj.sql_create() ) )
|
||||
|
||||
if isinstance( obj, self.CLASSES_NOT_TO_CACHE ):
|
||||
cache = None
|
||||
|
@ -285,7 +294,7 @@ class Database( object ):
|
|||
connection = self.get_connection()
|
||||
cursor = connection.cursor()
|
||||
|
||||
cursor.execute( sql_command )
|
||||
cursor.execute( self.unescape( sql_command ) )
|
||||
|
||||
row = self.__row_to_unicode( cursor.fetchone() )
|
||||
if not row:
|
||||
|
@ -317,7 +326,7 @@ class Database( object ):
|
|||
connection = self.get_connection()
|
||||
cursor = connection.cursor()
|
||||
|
||||
cursor.execute( sql_command )
|
||||
cursor.execute( self.unescape( sql_command ) )
|
||||
|
||||
objects = []
|
||||
row = self.__row_to_unicode( cursor.fetchone() )
|
||||
|
@ -352,7 +361,7 @@ class Database( object ):
|
|||
connection = self.get_connection()
|
||||
cursor = connection.cursor()
|
||||
|
||||
cursor.execute( sql_command )
|
||||
cursor.execute( self.unescape( sql_command ) )
|
||||
|
||||
if commit:
|
||||
connection.commit()
|
||||
|
@ -373,7 +382,7 @@ class Database( object ):
|
|||
if self.__backend == Persistent.SQLITE_BACKEND:
|
||||
cursor.executescript( sql_commands )
|
||||
else:
|
||||
cursor.execute( sql_commands )
|
||||
cursor.execute( self.unescape( sql_commands ) )
|
||||
|
||||
if commit:
|
||||
connection.commit()
|
||||
|
@ -430,15 +439,15 @@ class Database( object ):
|
|||
# generate a random id, but on the off-chance that it collides with something else already in
|
||||
# the database, try again
|
||||
next_id = Database.generate_id()
|
||||
cursor.execute( Object_type.sql_id_exists( next_id ) )
|
||||
cursor.execute( self.unescape( Object_type.sql_id_exists( next_id ) ) )
|
||||
|
||||
while cursor.fetchone() is not None:
|
||||
next_id = Database.generate_id()
|
||||
cursor.execute( Object_type.sql_id_exists( next_id ) )
|
||||
cursor.execute( self.unescape( Object_type.sql_id_exists( next_id ) ) )
|
||||
|
||||
# save a new object with the next_id to the database
|
||||
obj = Object_type( next_id )
|
||||
cursor.execute( obj.sql_create() )
|
||||
cursor.execute( self.unescape( obj.sql_create() ) )
|
||||
|
||||
if commit:
|
||||
connection.commit()
|
||||
|
|
|
@ -3363,6 +3363,44 @@ class Test_notebooks( Test_controller ):
|
|||
assert note.contents == contents + " bar"
|
||||
assert note.user_id == self.user.object_id
|
||||
|
||||
def test_save_new_note_with_backslashes( self ):
|
||||
self.login()
|
||||
|
||||
# save a completely new note
|
||||
contents = r"<h3>newest title</h3>c:\windows\foo\bar\baz.exe"
|
||||
new_note = Note.create( "55", contents )
|
||||
previous_revision = new_note.revision
|
||||
result = self.http_post( "/notebooks/save_note/", dict(
|
||||
notebook_id = self.notebook.object_id,
|
||||
note_id = new_note.object_id,
|
||||
contents = new_note.contents,
|
||||
startup = False,
|
||||
previous_revision = None,
|
||||
), session_id = self.session_id )
|
||||
|
||||
assert result[ "new_revision" ]
|
||||
assert result[ "new_revision" ] != previous_revision
|
||||
assert result[ "new_revision" ].user_id == self.user.object_id
|
||||
assert result[ "new_revision" ].username == self.username
|
||||
assert result[ "previous_revision" ] == None
|
||||
user = self.database.load( User, self.user.object_id )
|
||||
assert user.storage_bytes > 0
|
||||
assert result[ "storage_bytes" ] == user.storage_bytes
|
||||
assert result[ "rank" ] == 0.0
|
||||
|
||||
# make sure the new title is now loadable
|
||||
result = self.http_post( "/notebooks/load_note_by_title/", dict(
|
||||
notebook_id = self.notebook.object_id,
|
||||
note_title = new_note.title,
|
||||
), session_id = self.session_id )
|
||||
|
||||
note = result[ "note" ]
|
||||
|
||||
assert note.object_id == new_note.object_id
|
||||
assert note.title == new_note.title
|
||||
assert note.contents == contents
|
||||
assert note.user_id == self.user.object_id
|
||||
|
||||
def test_save_two_new_notes( self, startup = False ):
|
||||
self.login()
|
||||
|
||||
|
|
Reference in New Issue