Go to main content

Textpattern CMS support forum

You are not logged in. Register | Login | Help

#1 2010-03-29 00:54:47

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 11,273
Website GitHub

Attribute character limit

Been kicking this around with jakob for the last few hours trying to find which plugin was the cuplrit, and in the end we’ve come to the conclusion that there’s a limit to the number of characters you can put in an attribute, and that the results of doing so are server/implementation/PHP/unicorn dependent.

Background: we’re running an smd_query to extract an article from the database, then passing that through mem_simple_form / mem_form so the salient points of the article can be edited on the public side. A bit like mem_public_article but this has some special features I won’t bore you with.

One of the attributes to <txp:mem_form_textarea /> is default which allows us to put in the current text to display inside the textarea. Being frugal typists we chose default="{Body}" which worked very well… up to a point. Suddenly we started to get either a white screen of death or an Internal Server Error. After pleeenty diagnostics, it seemed to be size-dependent, but running the {Body} value through htmlspecialchars() seemed to fix it so we figured it was some kind of bizarre character sequence in particular articles.

But that also didn’t work in some cases so we eventually settled back on the ‘character limit’ theory. It seems to differ from server to server and implementation to implementation, but at last count I made it around 8000 chars; I’m guessing ~8Kb or 8192 is about the limit depending on the length of your tag name plus the number of attributes multiplied by the number you first thought of. Minus 42.

The solution to this conundrum is deceptively simple when you haven’t been banging your head against the screen for the best part of four hours:

<txp:variable name="the_body"> {Body}</txp:variable>

The container form of txp:variable doesn’t suffer from a size limit because it’s not parsed as an attribute. The only tricky thing to watch here is that if the body is empty for some reason, the variable is not created, thus you would get an error if you did this:

<txp:mem_form_textarea default='<txp:if_variable name="the_body" value=""><txp:variable name="the_body" /></txp:if_variable>' />

(and even if you removed the value="" bit)

Hence the cheeky little space character before the {Body} which sets the variable to something, even if it’s just a space.

So if anybody ever hits this kind of problem, that’s one way to approach it and hopefully we’ve saved you a few hours frustration.

But from a ‘why the hell does it happen’ perspective I’d like to know which part of the system is responsible for the limit. Is it the TXP parser? Or a line length thing as it reads each ‘line’ of the file/array containing your tags? Or some limit in a PHP function like, say, preg_match as it tracks back and forth trying to find the end of the string? Or is it likely to be some PHP memory limit being exceeded? Since it manifests itself in bizarre page behaviour — bits of the page go missing or stuff renders incorrectly as the limit is approached — all the way to a full-on Apache deathbomb / TXP white void, it’s a slippery beast to diagnose. If anybody knows or has some insight, I’d love to find out… primarily out of morbid curiosity.

Thanks, and I hope this might prove useful to someone one day.

Last edited by Bloke (2010-03-29 00:58:48)


The smd plugin menagerie — for when you need one more gribble of power from Textpattern. Bleeding-edge code available on GitHub.

Txp Builders – finely-crafted code, design and Txp

Offline

#2 2010-03-29 02:40:02

Gocom
Developer Emeritus
From: Helsinki, Finland
Registered: 2006-07-14
Posts: 4,533
Website

Re: Attribute character limit

Been there. Same happens on my test server that has absolutely no limits (expect 4 GB of memory).

Just plain 100 000 chars string, no /r or /ns, no charset errors, but still it fails. Instead it just crashing, it returns the tag source unparsed revealing everything from the same instance that point onwards. Everything else, expect those nested calls, works fine as long as no functions are “sliced”.

But, if the same 100 000 chars is inside $thing, it works just fine.

Last edited by Gocom (2010-03-29 02:49:25)

Offline

#3 2010-03-29 08:36:23

the_ghost
Plugin Author
From: Minsk, The Republic of Belarus
Registered: 2007-07-26
Posts: 907
Website

Re: Attribute character limit

Just a guess – may be regexp which is involed in parsing txp:tag attr="long_attr" stumbles at long attr?


Providing help in hacking ATM! Come to courses and don’t forget to bring us notebook and hammer! What for notebook? What a kind of hacker you are without notebok?

Offline

#4 2010-03-29 09:19:16

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 11,273
Website GitHub

Re: Attribute character limit

Good to know we’re not alone here then! My first thought, like yours the_ghost — after eventually clearing the plugins of any wrongdoing, and also discounting TXPs debugging/trace functions by setting Production Status to Live — was the regex in the splat() function reading the attributes. But it appeared the code wasn’t even getting that far. So I went further back to processTags() and started putting debug stuff in there. Then it dawned on me that I wasn’t seeing output because of the buffering, and the white screen of death was masking my attempts to see what was going on.

As soon as I added an exit; call after the debug diagnostics I saw results, so I went back and tried to step through the code again to find where the problem lay. Of course, the exit; statement meant TXP only parsed the first tag it came to on the page and not the one I actually wanted — d’oh — so I had to filter the output of debug_backtrace() to extract the name of the calling function and only print diagnostics/exit when it reached the tag I was interested in. Talk about a hassle.

I got so far through this mess and then gave up to find a workaround instead.

And you know what, I woke this morning and wondered why we didn’t just use mem_form_textarea’s container to hold the contents of the {Body} tag instead of using the default attribute and making up variables to fix a problem that we might never have found. Remind me to ask jakob if there’s a reason!


The smd plugin menagerie — for when you need one more gribble of power from Textpattern. Bleeding-edge code available on GitHub.

Txp Builders – finely-crafted code, design and Txp

Offline

#5 2010-03-29 13:11:28

ruud
Developer Emeritus
From: a galaxy far far away
Registered: 2006-06-04
Posts: 5,068
Website

Re: Attribute character limit

If you’re using PHP 5.2 or higher it might be related to the pcre.backtrack_limit setting.

Offline

#6 2010-03-29 14:19:12

jakob
Admin
From: Germany
Registered: 2005-01-20
Posts: 4,599
Website

Re: Attribute character limit

Stef, thanks for floating this conundrum.

My local setup is PHP 5.2.6, my online test site where Stef and I were testing was PHP 4, though (the site I transferred it to is also PHP4 and worse still MySQL 4.02 – just spent hours correcting the wonky special characters).

I didn’t know that mem_form_textarea can be used as a container tag, but we should try that if the contained goes into the default attribute.

@Jukka: so you didn’t have a solution, other than to take it out of the attribute?


TXP Builders – finely-crafted code, design and txp

Offline

Board footer

Powered by FluxBB