fu: Close-up of Fu, bringing a scoop of water to her mouth (Default)
fu ([personal profile] fu) wrote in [site community profile] changelog2011-08-24 05:08 am

[dw-free] Long entries get truncated silently

[commit: http://hg.dwscoalition.org/dw-free/rev/9ad6bf425b14]

http://bugs.dwscoalition.org/show_bug.cgi?id=3802

Handle entries which are over the character limit but aren't over the byte
limit. Modifies text_trim to return whether it did do truncation or not.

Patch by [personal profile] fu.

Files modified:
  • cgi-bin/ljprotocol.pl
  • cgi-bin/ljtextutil.pl
--------------------------------------------------------------------------------
diff -r 091b93ec61d8 -r 9ad6bf425b14 cgi-bin/ljprotocol.pl
--- a/cgi-bin/ljprotocol.pl	Tue Aug 23 21:28:13 2011 +0800
+++ b/cgi-bin/ljprotocol.pl	Wed Aug 24 13:07:27 2011 +0800
@@ -1017,10 +1017,17 @@
     }
     
 
-    # column width
+    # trim to column width
+
+    # we did a quick check for number of bytes earlier
+    # this one also handles the case of too many characters,
+    # even if we'd be within the byte limit
+    my $did_trim = 0;
+    $req->{'event'} = LJ::text_trim( $req->{'event'}, LJ::BMAX_EVENT, LJ::CMAX_EVENT, \$did_trim );
+    return fail( $err, 409 ) if $did_trim;
+
 
     $req->{'subject'} = LJ::text_trim($req->{'subject'}, LJ::BMAX_SUBJECT, LJ::CMAX_SUBJECT);
-    $req->{'event'} = LJ::text_trim($req->{'event'}, LJ::BMAX_EVENT, LJ::CMAX_EVENT);
     foreach (keys %{$req->{'props'}}) {
         # do not trim this property, as it's magical and handled later
         next if $_ eq 'taglist';
diff -r 091b93ec61d8 -r 9ad6bf425b14 cgi-bin/ljtextutil.pl
--- a/cgi-bin/ljtextutil.pl	Tue Aug 23 21:28:13 2011 +0800
+++ b/cgi-bin/ljtextutil.pl	Wed Aug 24 13:07:27 2011 +0800
@@ -470,9 +470,10 @@
 # </LJFUNC>
 sub text_trim
 {
-    my ($text, $byte_max, $char_max) = @_;
+    my ( $text, $byte_max, $char_max, $didtrim_ref ) = @_;
     $text = defined $text ? LJ::trim( $text ) : '';
     return $text unless $byte_max or $char_max;
+
     if (!$LJ::UNICODE) {
         $byte_max = $char_max if $char_max and $char_max < $byte_max;
         $byte_max = $char_max unless $byte_max;
@@ -486,12 +487,22 @@
     # than characters, so we can't inherit the other way.
     $char_max ||= $byte_max;
 
+    my $fake_scalar;
+    my $ref = ref $didtrim_ref ? $didtrim_ref : \$fake_scalar;
+
     while ($text =~ m/$utf_char/gco) {
-    last unless $char_max;
-        last if $byte_max and $cur + length($1) > $byte_max;
+        unless ( $char_max ) {
+            $$ref = 1;
+            last;
+        }
+        if ( $byte_max and $cur + length($1) > $byte_max ) {
+            $$ref = 1;
+            last;
+        }
         $cur += length($1);
         $char_max--;
     }
+
     return LJ::trim( substr( $text, 0, $cur ) );
 }
 
--------------------------------------------------------------------------------