Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2518348
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
166 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/CHANGELOG b/CHANGELOG
index 2773dafe4..86dd467e0 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,985 +1,986 @@
CHANGELOG Roundcube Webmail
===========================
+- Updated PEAR::Net_IDNA2 to 0.1.1
- Fix handling of comments inside an email address spec. (#1487673)
- Fix randomly disappearing folders list in IE (#1487704)
- Fix list column add/removal in IE (#1487703)
- Fix login redirect issues (#1487686)
- Require PHP 5.2.1 or greater
- Fix %h/%z variables in username_domain option (#1487701)
- Workaround for setting charset in case of malformed bodystructure response (#1487700)
- Fix impossible to subscribe to protected folders (#1487656)
- Fix setting timezone in Preferences (#1487705)
RELEASE 0.5
-----------
- Fix double-login/session issue (#1487104)
- Wrap HTML parts with <html><body> and add Doctype declaration (#1487098)
- Make rcube_autoload silently skip unknown classes (#1487109)
- Fix charset detection in vcards with encoded values (#1485542)
- Better CSS cursors for splitters (#1486874)
- Show the same message only once (#1487641)
- Fix namespaces handling (#1487649)
- Add handling of multifolder METADATA/ANNOTATION responses
- Fix handling of INBOX when personal namespace prefix is non-empty (#1487657)
- Fix handling square brackets in links (#1487672)
- Add description of 'use_https' option in main.inc.php.dist file
RELEASE 0.5-RC
--------------
- Plugin API: Add 'pass' argument in 'authenticate' hook (#1487134)
- Fix attachments of type message/rfc822 are not listed on attachments list
- Add 'login_lc' config option for case-insensitive authentication (#1487113)
- Fix window is blur'ed in IE when selecting a message (#1487316)
- Fix cursor position on compose form in Webkit browsers (#1486674)
- Fix setting charset of attachment filenames (#1487122)
- Allow setting autocomplete attribute for all inputs separately (#1487313)
- New Folder Manager UI
- Fix invalid Request when creating a folder (#1487443)
- Add folder size and quota indicator in folder manager (#1485780)
- Add possibility to move a subfolder into root folder (#1486791)
- Fix copying all messages in a folder copies only messages from current page
- Improve performance of moving or copying of all messages in a folder
- Fix plaintext versions of HTML messages don't contain placeholders for emotions (#1485206)
- Improve performance of folder rename and delete actions
- Better support for READ-ONLY and NOPERM responses handling (#1487083)
- Add confirmation message on purge/expunge command response
- Fix handling of untagged responses for AUTHENTICATE command (#1487450)
- Add username and IP address to log message on unsuccessful login (#1487626)
- Improved Mail-Followup-To and Mail-Reply-To headers handling
- Fix charset conversion for text attachments without charset specification (#1487634)
RELEASE 0.5-BETA
----------------
- Make session data storage more robust against garbage session data (#1487136)
- Config option for autocomplete on login screen
- Allow plugin templates to include local files (#1487133)
- List groups in address detail view and allow to subscribe/unsubscribe from there (#1486753)
- Messages caching: performance improvements, fixed syncing, fixes related with #1486748
- Add link to identities in compose window (#1486729)
- Add Internationalized Domain Name (IDNA) support (#1483894)
- Add option to automatically send read notifications for known senders (#1485883)
- Add option to "Return receipt" will be always checked (#1486352)
- Fix HTML to plain text conversion doesn't handle citation blocks (#1486921)
- Use custom sorting when SORT is disabled by IMAP admin (#1486959)
- Allow setting some washtml options from plugin (#1486578)
- Add option do bind for an individual LDAP address book (#1486997)
- Change reply prefix to display email address only if sender name doesn't exist (#1486550)
- Plugin API: improved 'abort' flag handling, added 'result' item in some hooks (#1486914)
- Fix mailto optional params in plain text messages aren't handled (#1487026)
- Add Reply-to-List feature (#1484252)
- Add Mail-Followup-To/Mail-Reply-To support (#1485547)
- Fix confirmation message isn't displayed after sending mail on Chrome (#1486177)
- Fix keyboard doesn't work with autocomplete list with Chrome (#1487029)
- Improve tabs to fixed width and add tabs in identities info (#1486974)
- Add unique index on users.username+users.mail_host
- Make htmleditor option more consistent and add option to use HTML on reply to HTML message (#1485840)
- Use empty envelope sender address for message disposition notifications (RFC 2298.3)
- Support SMTP Delivery Status Notifications - RFC 3461 (#1486142)
- Use css sprite image for messages list
- Add (different) attachment icon for messages of type multipart/report (#1486165)
- Prevent from inserting empty link when composing HTML message (#1486944)
- Add caching support in id2uid and uid2id functions (#1487019)
- Add SASL proxy authentication for SMTP (#1486693)
- Improve displaying of UI messages (#1486977)
- Fix double e-mail filed in identity form (#1487054)
- Display IMAP errors for LIST/THREAD/SEARCH commands (#1486905)
- Add LITERAL+ (IMAP4 non-synchronizing literals) support (RFC 2088)
- Add separate column for message status icon (#1486665)
- Add ACL extension support into IMAP classes (RFC 4314)
- Add ANNOTATEMORE extension support into IMAP classes (draft-daboo-imap-annotatemore)
- Add METADATA extension support into IMAP classes (RFC 5464)
- Fix decoding of e-mail address strings in message headers (#1487068)
- Fix handling of attachments when Content-Disposition is not inline nor attachment (#1487051)
- Improve performance of unseen messages counting (#1487058)
- Improve performance of messages counting using ESEARCH extension (RFC4731)
- Add LIST-STATUS support in rcube_imap_generic class (RFC 5819)
- Add SASL-IR support in IMAP (RFC 4959)
- Add LOGINDISABLED support (RFC 2595)
- Add support for AUTH=PLAIN in IMAP authentication
- Re-implemented SMTP proxy authentication support
- Add support for IMAP proxy authentication (#1486690)
- Add support for AUTH=DIGEST-MD5 in IMAP (RFC 2831)
- Fix parent folder with unread subfolder not bold when message is open (#1487078)
- Add basic IMAP LIST's \Noselect option support
- Add support for selection options from LIST-EXTENDED extension (RFC 5258)
- Don't list subscribed but non-existent folders (#1486225)
- Fix handling of URLs with tilde (~) or semicolon (;) character (#1487087, #1487088)
- Plugin API: added 'contact_form' hook
- Add SORT=DISPLAY support (RFC 5957)
- Plugin API: add possibility to disable plugin in AJAX mode, 'noajax' property
- Plugin API: add possibility to disable plugin in framed mode, 'noframe' property
- Improve performance of setting IMAP flags using .SILENT suffix
- Improve performance of message cache status checking with skip_disabled=true
- Support contact's email addresses up to 255 characters long (#1487095)
- Add option to place replies in the folder of the message being replied to (#1485945)
- Add missing confirmation/error messages on contact/group/message actions (#1486845)
- Add 'loading' message on message move/copy/delete/mark actions
- Improve responsiveness of messages displaying (#1486986)
- Add option for minimum length of autocomplete's string (#1486428)
- Fix operations on messages in unsubscribed folder (#1487107)
- Add support for shared folders (#1403507)
- Fix handling of folders with name "0" (#1487119)
- Fix handling of folders with "<>" characters in name
- jQuery 1.4.4
- Fix handling of HTML entity strings in plain text messages
- Fix focused elements aren't unfocused when clicking on the list (#1487123)
- Fix error in MSSQL DDL scripts (#1487112)
- Lock submit button in onsubmit event on login page (#1487036)
- Don't set attachment's charset in Content-type header (#1487122)
- Fix handling of message bodies (quoted-printable encoded) with NULL characters (#1486189)
- Add workaround for MSOE's multipart/related messages with non-related attachments
RELEASE 0.4.2
-------------
- Fix handling of backslash as IMAP delimiter
- Fix charset replacement in HTML message bodies (#1487021)
- Fix: contact group input is empty when using rename action more than once on the same group record
- Fix "Server Error! (Not Found)" when using utils/save-pref action (#1487023)
- Fix handling of Thunderbird's vCards (#1487024)
RELEASE 0.4.1
-------------
- Fix space-stuffing in format=flowed messages (#1487018)
- Fix msgexport.sh now using the new imap wrapper
- Avoid displaying password on shell (#1486947)
- Only lower-case user name if first login attempt failed (#1486393)
- Make alias setting in squirrelmail_usercopy plugin configurable (patch by pommi, #1487007)
- Prevent from saving a non-existing skin path in user prefs (#1486936)
- Improve handling of single-part messages with bogus BODYSTRUCTURE (#1486898)
- Fix path to SQL files when using pgsql/mysqli/sqlsrv drivers (#1486902)
- Fix upgrade script for SQLite (#1486903)
- Fixes in SQL init script + added update script for MSSQL database
- Remove redundant date in syslog messages (#1486945)
- Fix contacts list page controls when a group is selected (#1486946)
- Fix SMTP test in Installer (#1486952)
- Fix "Select all" causes message to be opened in folder with exactly one message (#1486913)
- Fix Tab key doesn't work in HTML editor in Google Chrome (#1486925)
- Fix TinyMCE uses zh_CN when zh_TW locale is set (#1486929)
- Fix TinyMCE buttons are hidden in Opera (#1486922)
- Fix JS error on IE when trying to send HTML message with enabled spellchecker (#1486940)
- Display inline images with known extensions and non-image content-type (#1486934)
- Fix "Threaded" checkbox after subfolder creation (#1486928)
- Fix timezone string in sent mail (#1486961)
- Show disabled checkboxes for protected folders instead of dots (#1485498)
- Added fieldsets in Identity form, added 'identity_form' hook
- Re-added 'Close' button in upload form (#1486930, #1486823)
- Fix handling of charsets with LATIN-* label
- Fix messages background image handling in some cases (#1486990)
- Fix format=flowed handling (#1486989)
- Fix when IMAP connection fails in 'get' action session shouldn't be destroyed (#1486995)
- Fix list_cols is not updated after column dragging (#1486999)
- Support %z variable in host configuration options (#1487003)
RELEASE 0.4
-----------
- Fix disapearing upload form disapears when user selects a file on Safari (#1486823)
- Don't replace error messages with loading info (#1486300)
- Fix JS errors on compose mode switch (#1486870)
- Fix message structure parsing when it lacks optional fields (#1486881)
- Include all recipients in sendmail log
- Support HTTP_X_FORWARDED_PROTO header for HTTPS detecting (#1486866)
- Fix default IMAP port configuration (#1486864)
- Create Sent folder when starting to compose a new message (#1486802)
- Fix handling of messages with Content-Type: application/* and no filename (#1484050)
- Improved compose screen: resizable body and attachments list, vertical splitter, options menu
- Fix RC forgets search results (#1483883)
- TinyMCE 3.3.7
- Improve parsing of styled empty tags in HTML messages (#1486812)
- Add %dc variable support in base_dn/bind_dn config (#1486779)
- Add button to hide/unhide the preview pane (#1484215)
- Fix no-cache headers on https to prevent content caching by proxies (#1486798)
- Fix attachment filenames broken with TNEF decoder using long filenames (#1486795)
- Use user's timezone in Date header, not server's timezone (#1486119)
- Add option to set separate footer for HTML messages (#1486660)
- Add real SMTP error description to displayed error messages (#1485927)
- Fix some IMAP errors handling when opening the message (#1485443)
- Fix related parts aren't displayed when got mimetype other than image/* (#1486432)
- Multiple identity and database support for squirrelmail_usercopy plugin (#1486517)
- Support dynamic hostname (%d/%n) variables in configuration options (#1485438)
- Add 'messages_list' hook (#1486266)
- Add request* event triggers in http_post/http_request (#1486054)
- Fix use RFC-compliant line-delimiter when saving messages on IMAP (#1486712)
- Add 'imap_timeout' option (#1486760)
- Fix forwarding of messages with winmail attachments
- Fix handling of uuencoded attachments in message body (#1485839)
- Added list_mailboxes hook in rcube_imap::list_unsubscribed() (#1486668)
- Fix wrong message on file upload error (#1486725)
- Add support for data URI scheme [RFC2397] (#1486740)
- Added 'actionbefore', 'actionafter', 'responsebefore', 'responseafter' events
- Fix double-addition of e-mail domain to content ID in HTML images
- Read and send messages with format=flowed (#1484370), fixes word wrapping issues (#1486543)
- Fix duplicated attachments when forwarding a message (#1486487)
- Fix message/rfc822 attachments containing only attachments are not parsed properly (#1486743)
- Fix %00 character in winmail.dat attachments names (#1486738)
- Fix handling errors of folder deletion (#1486705)
- Parse untagged CAPABILITY response for LOGIN command (#1486742)
- Renamed all php-cli scripts to use .sh extension
- Some files from /bin + spellchecking actions moved to the new 'utils' task
- Added thread tree icons
- Extend contact groups support (#1486682)
- Fix check-recent action issues and performance (#1486526)
- Fix messages order after checking for recent (#1484664)
- Fix autocomplete shows entries without email (#1486452)
- Fix listupdate event doesn't trigger on search response (#1486708)
- Fix select_all_mode value after selecting a message (#1486720)
- Set focus to editor on reply in HTML mode (#1486632)
- Fix composing in HTML jumps cursor to body instead of recipients (#1486674)
- Allow columns order change per user - drag&drop (#1485795)
- Add References header in read receipt (#1486681)
- Fix database constraint violation when opening a message (#1486696)
- Add 'loading' message while login is in progress (#1486667)
- Fix quota_zero_as_unlimited (#1486662)
- Fix folder subscription checking (#1486684)
- Fix INBOX appears (sometimes) twice in mailbox list (#1486672)
- Fix listing of attachments of some types e.g. "x-epoc/x-sisx-app" (#1486653)
- Fix DB Schema checking when some db_table_* options are not set (#1486654)
RELEASE 0.4-beta
----------------
- Add sizelimit and timelimit variables in LDAP config (#1486544)
- Hide IMAP host dropdown when single host is defined (#1486326)
- Add images pre-loading on login page (#1451160)
- Add HTTP_X_REAL_IP and HTTP_X_FORWARDED_FOR to successful logins log (#1486441)
- Fix setting spellcheck languages with extended codes (#1486605)
- Fix messages list scrolling in FF3.6 (#1486472)
- Fix quicksearch input focus (#1486637)
- Always set changed date when flagging a DB record as deleted + provide a cleanup script
- Fix address book/group selection (#1486619)
- Assign newly created contacts to the active group (#1486626)
- Added option not to mark messages as read when viewed in preview pane (#1485012)
- Allow plugins modify the Sent folder when composing (#1486548)
- Added optional (max_recipients) support to restrict total number of recipients per message (#1484542)
- Re-organize editor buttons, add blockquote and search buttons
- Make possible to write inside or after a quoted html message (#1485476)
- Fix bugs on unexpected IMAP connection close (#1486190, #1486270)
- Iloha's imap.inc rewritten into rcube_imap_generic class
- Added contact groups in address book (not finished yet)
- Added PageUp/PageDown/Home/End keys support on lists (#1486430)
- Added possibility to select all messages in a folder (#1484756)
- Added 'imap_force_caps' option for after-login CAPABILITY checking (#1485750)
- Password: Support dovecotpw encryption
- TinyMCE 3.3.1
- Implemented messages copying using drag&drop + SHIFT (#1484086)
- Improved performance of folders operations (#1486525)
- Fix blocked.gif attachment is not attached to the message (#1486516)
- Managesieve: import from Horde-INGO
- Managesieve: support for more than one match (#1486078)
- Managesieve: support for selectively disabling rules within a single sieve script (#1485882)
- Threaded message listing now available
- Added sorting by ARRIVAL and CC
- Message list columns configurable by the user
- Removed 'index_sort' option, now we're using empty 'message_sort_col' for this
- virtuser_query: support other identity data (#1486148)
- Options virtuser_* replaced with virtuser_* plugins
- Plugin API: Implemented 'email2user' and 'user2email' hooks
- Fix forwarding message omits CC header (#1486305)
- Add 'default_charset' option to user preferences (#1485451)
- Add 'delete_always' option to user preferences
- Support/Require tls:// prefix in 'smtp_server' option for TLS connections
- Fix inconsistent behaviour of 'delete_always' option (#1486299)
- Fix deleting all messages from last list page (#1486293)
- Flag original messages when sending a draft (#1486203)
- Changed signature separator when top-posting (#1486330)
- Let the admin define defaults for search modifiers (#1485897)
- Fix long e-mail addresses validation (#1486453)
- Remember search modifiers in user prefs (#1486146)
- Added force_7bit option to force MIME encoding of plain/text messages (#1486510)
- Use case sensitive check when checking for default folders (#1486346)
- Fix checking for new mail: now checks unseen count of inbox (#1485794)
- Improve performance by avoiding unnecessary updates to the session table (#1486325)
- Fix invalid <font> tags which cause HTML message rendering problems (#1486521)
- Fix CVE-2010-0464: Disable DNS prefetching (#1486449)
- Fix Received headers to behave better with SpamAssassin (#1486513)
- Password: Make passwords encoding consistent with core, add 'password_charset' global option (#1486473)
- Fix adding contacts SQL error on mysql (#1486459)
- Squirrelmail_usercopy: support reply-to field (#1486506)
- Fix IE spellcheck suggestion popup issue (#1486471)
- Fix email address auto-completion shows regexp pattern (#1486258)
- Fix merging of configuration parameters: user prefs always survive (#1486368)
- Fix quota indicator value after folder purge/expunge (#1486488)
- Fix external mailto links support for use as protocol handler (#1486037)
- Fix attachment excessive memory use, support messages of any size (#1484660)
- Fix setting task name according to auth state
- Password: fix vpopmaild driver (#1486478)
- Add workaround for MySQL bug [http://bugs.mysql.com/bug.php?id=46293] (#1486474)
- Fix quoted text wrapping when replying to an HTML email in plain text (#1484141)
- Fix handling of extended mailto links (with params) (#1486354)
- Fix sorting by date of messages without date header on servers without SORT (#1486286)
- Fix inconsistency when not using default table names (#1486467)
- Fix folder rename/delete buttons do not appear on creation of first folder (#1486468)
- Fix character set conversion fails on systems where iconv doesn't accept //IGNORE (#1486375)
- Log in performance: Create default folders on first login only
- Import contacts into the selected address book (by Phil Weir)
- Add support for MDB2's 'sqlsrv' driver (#1486395)
- Use jQuery-1.4
- Removed problematic browser-caching of messages
- Fix incompatybility with suhosin.executor.disable_emodifier (#1486321)
- Use PLAIN auth when CRAM fails and imap_auth_type='check' (#1486371)
- Fix removal of <title> tag from HTML messages (#1486432)
- Fix 'force_https' to specified port when URL contains a port number (#1486411)
- Fix to-text converting of HTML entities inside b/strong/th/hX tags (#1486422)
- Bug in spellchecker suggestions when server charset != UTF8 (#1486406)
- Managesieve: Fix requires generation for multiple actions (#1486397)
- Fix LDAP problem with special characters in RDN (#1486320)
- Improved handling of message parts of type message/rfc822
- Plugin API: added 'quota' hook
- Fix parsing conditional comments in HTML messages (#1486350)
- Use built-in json_encode() for proper JSON format in AJAX replies
- Allow setting only selected params in 'message_compose' hook (#1486312)
- Plugin API: added 'message_compose_body' hook (#1486285)
- Fix counters of all folders are checked in 'getunread' action with check_all_folders disabled (#1486128)
- Fix displaying alternative parts in messages of type message/rfc822 (#1486246)
- Fix possible messages exposure when using Roundcube behind a proxy (#1486281)
- Fix unicode para and line separators in javascript response (#1486310)
- Additional_message_headers: allow unsetting headers, support plugin's config file (#1486268)
- Fix displaying of hidden directories in skins list (#1486301)
- Fix open_basedir restriction error when reading skins list (#1486304)
- Fix pasting from Office apps into html editor (#1486271)
- Fix empty <a> tags parsing (#1486272)
- Don't cut off attachment names when using non-RFC2231 encoding (#1485515)
- Allow inserting signatures above replied message body (#1484272)
- Managesieve 2.0: multi-script support
- Fix imap_auth_type regression (#1486263)
RELEASE 0.3.1
------------------
- Specify toolbar container in compose template (#1486247)
- Fix $_SERVER['HTTPS'] check for SSL forcing on IIS (#1486243)
- Avoid unnecessary page loads for selected tab (#1486032)
- Fix quota indicator issues by content generation on client-size (#1486197, #1486220)
- Don't display disabled sections in Settings (#1486099)
- Added server-side e-mail address validation with 'email_dns_check' option (#1485857)
- Fix login page loading into an iframe when session expires (#1485952)
- Allow setting port number in 'force_https' option (#1486091)
- Option 'force_https' replaced by 'force_https' plugin
- Fix IE issue with non-UTF-8 characters in AJAX response (#1486159)
- Partially fixed "empty body" issue by showing raw body of malformed message (#1486166)
- Fix importing/sending to email address with whitespace (#1486214)
- Added XIMSS (CommuniGate) driver for Password plugin
- Fix newly attached files are not saved in drafts w/o editing any text (#1486202)
- Added attachment upload indicator with parallel upload (#1486058)
- Use default_charset for bodies of messages without charset definition (#1486187)
- Password: added cPanel driver
- Fix return to first page from e-mail screen (#1486105)
- Fix handling HTML comments in HTML messages (#1486189)
- Fix folder/messagelist controls alignment - icons used (#1486072)
- Fix LDAP addressbook shows 'Contact not found' error sometimes (#1486178)
- Fix cache status checking + improve cache operations performance (#1486104)
- Prevent from setting INBOX as any of special folders (#1486114)
- Fix regular expression for e-mail address (#1486152)
- Fix Received header format
- Implemented sorting by message index - added 'index_sort' option (#1485936)
- Fix dl() use in installer (#1486150)
- Added 'ldap_debug' option
- Fix "Empty startup greeting" bug (#1486085)
- Fix setting user name in 'new_user_identity' plugin (#1486137)
- Fix incorrect count of new messages in folder list when using multiple IMAP clients (#1485995)
- Fix all folders checking for new messages with disabled caching (#1486128)
- Support skins in 'archive' and 'markasjunk' plugins
- Added 'html_editor' hook (#1486068)
- Fix DB constraint violation when populating messages cache (#1486052)
- Password: added password strength options (#1486062)
- Fix LDAP partial result warning (#1485536)
- Fix delete in message view deletes permanently with flag_for_deletion=true (#1486101)
- Use faster/secure mt_rand() (#1486094)
- Fix roundcube hangs on empty inbox with bincimapd (#1486093)
- Fix wrong headers for IE on servers without $_SERVER['HTTPS'] (#1485926)
- Force IE style headers for attachments in non-HTTPS session, 'use_https' option (#1485655)
- Check 'post_max_size' for upload max filesize (#1486089)
- Password Plugin: Fix %d inserts username instead of domain (#1486088)
- Fix rcube_mdb2::affected_rows() (#1486082)
RELEASE 0.3-stable
------------------
- Fix gn and givenName should be synonymous in LDAP addressbook (#1485892)
- Add mail_domain to LDAP email entries without @ sign (#1485201)
- Fix saving empty values in LDAP contact data (#1485781)
- Fix LDAP contact update when RDN field is changed (#1485788)
- Fix LDAP attributes case senitivity problems (#1485830)
- Fix LDAP addressbook browsing when only one directory is used (#1486022)
- Fix endless loop on error response for APPEND command (#1486060)
- Don't require date.timezone setting in installer (#1485989)
- Fix date sorting problem with Courier IMAP server (#1486065)
- Unselect pressed buttons on mouse up (#1485987)
- Don't set php_value error_log in .htaccess but mention in INSTALL (#1485924)
- Fix too small status/flag/attachment columns in Safari 4 (#1486063)
- Fix selection disabling while dragging splitter in webkit browsers (#1486056)
- Added 'new_messages' plugin hook (#1486005)
- Added 'logout_after' plugin hook (#1486042)
- Added 'message_compose' hook
- Added 'imap_connect' hook (#1485956)
- Fix vcard_attachments plugin (#1486035)
- Updated PEAR::Auth_SASL to 1.0.3 version
- Use sequence names only with PostgreSQL (#1486018)
- Re-designed User Preferences interface
- Fix MS SQL DDL (#1486020)
- Fix rcube_mdb2.php: call to setCharset not implemented in mssql driver (#1486019)
- Added 'display_next' option
- Fix rcube_mdb2::unixtimestamp for MS SQL (#1486015)
- Fix HTML washing to respect character encoding
- Fix endless loop in iil_C_Login() with Courier IMAP (#1486010)
- Fix #messagemenu display on IE (#1486006)
- Speedup UI by using sprites for (toolbar) buttons
- Fix charset names with X- prefix handling
- Fix displaying of HTML messages with unknown/malformed tags (#1486003)
RELEASE 0.3-RC1
---------------
- Fix import of vCard entries with params (#1485453)
- Fix HTML messages output with empty block elements (#1485974)
- Use request tokens to protect POST requests from CSRF
- Added hook when killing a session
- Added hook to write_log function (#1485971)
- Performance improvements by use UID commands (#1485690)
- Fix HTML editor tabIndex setting (#1485972)
- Added 'imap_debug' and 'smtp_debug' options
- Support strftime's format modifiers in date_* options (#1484806)
- Support %h variable in 'smtp_server' option (#1485766)
- Show SMTP errors in browser (#1485927)
- Allow WBR tag in HTML message (#1485960)
- Use spl_autoload_register() instead of __autoload (#1485947)
- Add hook for identities listing (#1485958)
- Trigger hook 'smtp_connect' when opening an SMTP connection (#1485954)
- Added config option to enforce HTTPS connections
- Fix non-unicode characters caching in unicode database (#1484608)
- Performance improvements of messages caching
- Fix empty Date header issue (#1485923)
- Open collapsed folders during drag & drop (#1485914)
- Fixed link text replacements (#1485789)
- Also trigger 'insertrow' events on page load (#1485826)
- No link on subject in IE browsers (#1484913)
- Fixed filename encoding according to RFC2231 (#1485875)
- Added message Edit feature (#1483891, #1484440)
- Fix message Etag generation for counter issues (#1485623)
- Fix messages searching on MailEnable IMAP (#1485762)
- Fixed many 'skip_deleted' issues (#1485634)
- Fixed messages list sorting on servers without SORT capability
- Colorized signatures in plain text messages
- Reviewed/fixed skip_deleted/read_when_deleted/flag_for_deletion options handling in UI
- Fix displaying of big maximum upload filesize (#1485889)
- Added possibility to invert messages selection
- After move/delete from 'show' action display next message instead of messages list (#1485887)
- Fixed problem with double quote at the end of folder name (#1485884)
- Speedup UI by using CSS sprites and etags/expires/deflate in Apache config (#1484858,#1485800)
- Support UID EXPUNGE: remove only moved/deleted messages
- Add drag cancelling with ESC key (#1484344)
- Support initial identity name from virtuser_query (#1484003)
- Added message menu, removed Print and Source buttons
- Added possibility to save message as .eml file (#1485861)
- Added 1 minute interval in autosave options (#1485854)
- Support UTF-7 encoding in messages (#1485832)
- Better support for malformed character names (#1485758)
RELEASE 0.3-BETA
----------------
- Plugin API + jQuery engine
- Added possibility to encrypt received header, option 'http_received_header_encrypt',
added some more logic in encrypt/decrypt functions for security
- Fix Answered/Forwarded flag setting for messages in subfolders
- Fix autocomplete problem with capital letters (#1485792)
- Support UUencode content encoding (#1485839)
- Minimize chance of race condition in session handling (#1485659, #1484678)
- Fix session handling on non-session SQL query error (#1485734)
- Fix html editor mode setting when reopening draft message (#1485834)
- Added quick search box menu (#1484304)
- Fix wrong column sort order icons (#1485823)
- Updated TinyMCE to 3.2.3 version
- Fix attachment names encoding when charset isn't specified in attachment part (#1484969)
- Fix message normal priority problem (#1485820)
- Fix autocomplete spinning wheel does not disappear (#1485804)
- Added log_date_format option (#1485709)
- Fix text wrapping in HTML editor after switching from plain text to HTML (#1485521)
- Fix auto-complete function hangs with plus sign (#1485815)
- Fix AJAX requests errors handler (#1485000)
- Speed up message list displaying on IE
- Fix read/write database recognition (#1485811)
RELEASE 0.2.2
-------------
- Fix quicksearchbox look in Chrome and Konqueror (#1484841)
- Fix UTF-8 byte-order mark removing (#1485514)
- Fix folders subscribtions on Konqueror (#1484841)
- Fix debug console on Konqueror and Safari
- Fix messagelist focus issue when modifying status of selected messages (#1485807)
- Support STARTTLS in IMAP connection (#1485284)
- Fix DEL key problem in search boxes (#1485528)
- Support several e-mail addresses per user from virtuser_file (#1485678)
- Fix drag&drop with scrolling on IE (#1485786)
- Fix adding signature separator in html mode (#1485350)
- Fix opening attachment marks message as read (#1485803)
- Fix 'temp_dir' does not support relative path under Windows (#1484529)
- Fix "Initialize Database" button missing from installer (#1485802)
- Fix compose window doesn't fit 1024x768 window (#1485396)
- Fix service not available error when pressing back from compose dialog (#1485552)
- Fix using mail() on Windows (#1485779)
- Fix word wrapping in message-part's <PRE>s for printing (#1485787)
- Fix incorrect word wrapping in outgoing plaintext multibyte messages (#1485714)
- Fix double footer in HTML message with embedded images
- Fix TNEF implementation bug (#1485773)
- Fix incorrect row id parsing for LDAP contacts list (#1485784)
- Fix 'mode' parameter in sqlite DSN (#1485772)
RELEASE 0.2.1
------------------
- Use US-ASCII as failover when Unicode searching fails (#1485762)
- Fix errors handling in IMAP command continuations (#1485762)
- Fix FETCH result parsing for servers returning flags at the end of result (#1485763)
- Fix datetime columns defaults in mysql's DDL (#1485641)
- Fix attaching more than nine inline images (#1485759)
- Support 'UNICODE-1-1-UTF-7' alias for UTF-7 encoding (#1485758)
- Fix mime-type detection using a hard-coded map (#1485311)
- Don't return empty string if charset conversion failed (#1485757)
- Disable concurrent autocomplete query results display (#1485743)
- Fix new lines stripped from message footer (#1485751)
- Fix IE problem with mouse click autocomplete (#1485739)
- Fix html body washing on reply/forward + fix attachments handling (#1485676)
- Fix multiple recipients input parsing (#1485733)
- Fix replying to message with html attachment (#1485676)
- Use default_charset for messages without specified charset (#1485661, #1484961)
- Support non-standard "GMT-XXXX" literal in date header (#1485729)
- Added TNEF support to decode MS Outlook attachments (winmail.dat)
- Fix "value continuation" MIME headers by adding required semicolon (#1485727)
- Fix pressing select all/unread multiple times (#1485723)
- Fix selecting all unread does not honor new messages (#1485724)
- Fix some base64 encoded attachments handling (#1485725)
- Support NGINX as IMAP backend: better BAD response handling (#1485720)
- Performance fix: don't fetch attachment parts headers twice to parse filename
- Fix checking for recent messages on various IMAP servers (#1485702)
- Performance fix: Don't fetch quota and recent messages in "message view" mode
- Fix displaying of alternative-inside-alternative messages (#1485713)
- Fix MDNSent flag checking, use arbitrary keywords (asterisk) flag (#1485706)
- Fix creation of folders with '&' sign in name
- Fix parsing of email addresses without angle brackets (#1485693)
- Save spellcheck corrections when switching from plain to html editor (and spellchecking is on)
- Fix large search results on server without SORT capability (#1485668)
- Get rid of preg_replace() with eval modifier and create_function usage (#1485686)
- Bring back <base> and <link> tags in HTML messages
- Fix XSS vulnerability through background attributes as reported by Julien Cayssol
- Fix problems with backslash as IMAP hierarchy delimiter (#1484467)
- Secure vcard export by getting rid of preg's 'e' modifier use (#1485689)
- Fix authentication when submitting form with existing session (#1485679)
- Allow absolute URLs to images in HTML messages/sigs (#1485666)
- Fix message body which contains both inline attachments and emotions
- Fix SQL query execution errors handling in rcube_mdb2 class (#1485509)
- Fix address names with '@' sign handling (#1485654)
- Improve messages display performance
- Fix messages searching with 'to:' modifier
RELEASE 0.2-STABLE
------------------
- Fix mark popup in IE 7 (#1485369)
- Fix line-break issue when copy & paste in Firefox (#1485425)
- Fix autocomplete "unknown server error" (#1485637)
- Fix STARTTLS before AUTH in SMTP connection (#1484883)
- Support multiple quota values in QUOTAROOT resonse (#1485626)
- Only abbreviate file name for IE < 7 browsers (#1485063)
- Performance: allow setting imap rootdir and delimiter before connect (#1485172)
- Fix sorting of folders with more than 2 levels (#1485569)
- Fix search results page jumps in LDAP addressbook (#1485253)
- Fix empty line before the signature in IE (#1485351)
- Fix horizontal scrollbar in preview pane on IE (#1484633)
- Add Robots meta tag in login page and installer (#1484846)
- Added 'show_images' option, removed 'addrbook_show_images' (#1485597)
- Option to check for new mails in all folders (#1484374)
- Don't set client busy when checking for new messages (#1485276)
- Allow UTF-8 folder names in config (#1485579)
- Add junk_mbox option configuration in installer (#1485579)
- Do serverside addressbook queries for autocompletion (#1485531)
- Allow setting attachment col position in 'list_cols' option
- Allow override 'list_cols' via skin (#1485577)
- Fix 'cache' table cleanup on session destroy (#1485516)
- Increase speed of session destroy and garbage clean up
- Fix session timeout when DB server got clock skew (#1485490)
- Fix handling of some malformed messages (#1484438)
- Speed up raw message body handling
- Better HTML entities conversion in html2text (#1485519)
- Fix big memory consumption and speed up searching on servers without SORT capability
- Fix setting locale to tr_TR, ku and az_AZ (#1485470)
- Use SORT for searching on servers with SORT capability
- Added message status filter
- Fix empty file sending (#1485389)
- Improved searching with many criterias (calling one SEARCH command)
- Fix HTML editor initialization on IE (#1485304)
- Add warning when switching editor mode from html to plain (#1485488)
- Make identities list scrollable (#1485538)
- Fix problem with numeric folder names (#1485527)
- Added BYE response simple support to prevent from endless loops in imap.inc (#1483956)
- Fix unread message unintentionally marked as read if read_when_deleted=true (#1485409)
- Remove port number from SERVER_NAME in smtp_helo_host (#1485518)
- Don't send disposition notification receipts for messages marked as 'read' (#1485523)
- Added 'keep_alive' and 'min_keep_alive' options (#1485360)
- Added option 'identities_level', removed 'multiple_identities'
- Allow deleting identities when multiple_identities=false (#1485435)
- Added option focus_on_new_message (#1485374)
- Fix html2text class autoloading on Windows (#1485505)
- Fix html signature formatting when identity save error occured (#1485426)
- Add feedback and set busy when moving folder (#1485497)
- Fix 'Empty' link visibility for some languages e.g. Slovak (#1485489)
- Fix messages count bar overlapping (#1485270)
- Fix adding signature in drafts compose mode (#1485484)
- Fix iil_C_Sort() to support very long and/or divided responses (#1485283)
- Fix matching case sensitivity when setting identity on reply (#1485480)
- Prefer default identity on reply
- Fix imap searching on ISMail server (#1485466)
- Add css class for flagged messages (#1485464)
- Write username instead of id in sendmail log (#1485477)
- Fix htmlspecialchars() use for PHP version < 5.2.3 (#1485475)
- Fix js keywords escaping in json_serialize() for IE/Opera (#1485472)
- Added bin/killcache.php script (#1485434)
- Add support for SJIS, GB2312, BIG5 in rc_detect_encoding()
- Fix vCard file encoding detection for non-UTF-8 strings (#1485410)
- Add 'skip_deleted' option in User Preferences (#1485445)
- Minimize "inline" javascript scripts use (#1485433)
- Fix css class setting for folders with names matching defined classes names (#1485355)
- Fix race conditions when changing mailbox
- Fix spellchecking when switching to html editor (#1485362)
- Fix compose window width/height (#1485396)
- Allow calling msgimport.sh/msgexport.sh from any directory (#1485431)
- Localized filesize units (#1485340)
- Better handling of "no identity" and "no email in identity" situations (#1485117)
- Added 'mime_param_folding' option with possibility to choose long/non-ascii attachment names encoding eg. to be readable in MS Outlook/OE (#1485320)
- Added "advanced options" feature in User Preferences
- Fix unread counter when displaying cached massage in preview panel (#1485290)
- Fix htmleditor spellchecking on MS Windows (#1485397)
- Fix problem with non-ascii attachment names in Mail_mime (#1485267, #1485096)
- Fix language autodetection (#1485401)
- Fix button label in folders management (#1485405)
- Fix collapsed folder not indicating unread msgs count of all subfolders (#1485403)
- Fix handling of apostrophes in filenames decoded according to rfc2231
RELEASE 0.2-BETA
----------------
- Made config files location configurable (#1485215)
- Reduced memory footprint when forwarding attachments (#1485345)
- Allow and use spellcheck attribute for input/textarea fields (#1485060)
- Added icons for forwarded/forwarded+replied messages (#1485257)
- Added Reply-To to forwarded emails (#1485315)
- Display progress message for folders create/delete/rename (#1485357)
- Smart Tags and NOBR tag support in html messages (#1485363, #1485327)
- Redesign of the identities settings (#1484042)
- Add config option to disable creation/deletion of identities (#1484498)
- Added 'sendmail_delay' option to restrict messages sending interval (#1484491)
- Added vertical splitter for folders list resizing
- Added possibility to view all headers in message view
- Fixed splitter drag/resize on Opera (#1485170)
- Fixed quota img height/width setting from template (#1484857)
- Refactor drag & drop functionality. Don't rely on browser events anymore (#1484453)
- Insert "virtual" folders in subscription list (#1484779)
- Added link to open message in new window
- Enable export of address book contacts as vCard
- Add feature to import contacts from vcard files (#1326103)
- Respect Content-Location headers in multipart/related messages according to RFC2110 (#1484946)
- Allowed max. attachment size now indicated in compose screen (#1485030)
- Also capture backspace key in list mode (#1484566)
- Allow application/pgp parts to be displayed (#1484753)
- Correctly handle options in mailto-links (#1485228)
- Immediately save sort_col/sort_order in user prefs (#1485265)
- Truncate very long (above 50 characters) attachment filenames when displaying
- Allow to auto-detect client language if none set (#1484434)
- Auto-detect the client timezone (user configurable)
- Add RFC2231 header value continuations support for attachment filenames + hack for servers that not support that feature
- Fix Reply-To header displaying (#1485314)
- Mark form buttons that provide the most obvious operation (mainaction)
- Added option 'quota_zero_as_unlimited' (#1484604)
- Added PRE handling in html2text class (#1484740)
- Added folder hierarchy collapsing
- Added options to use syslog instead of log file (#1484850)
- Added Logging & Debugging section in Installer
- Fix In-Reply-To and References headers when composing saved draft message (#1485288)
- Fix html message charset conversion for charsets with underline (#1485287)
- Fix buttons status after contacts deletion (#1485233)
- Fix escaping of To: and From: fields when building message body for reply or forward in the HTML editor (#1484904)
- Use current mailbox name in template (#1485256)
- Better fix for skipping untagged responses (#1485261)
- Added pspell support patch by Kris Steinhoff (#1483960)
- Enable spellchecker for HTML editor (#1485114)
- Respect spellcheck_uri in tinyMCE spellchecker (#1484196)
- Case insensitive contacts searching using PostgreSQL (#1485259)
- Make default imap folders configurable for each user (#1485075)
- Save outgoing mail to selectable folder (#1324581)
- Fix hiding of mark menu when clicking th button again (#1484944)
- Use long date format in print mode (#1485191)
- Updated TinyMCE to version 3.1.0.1
- Re-enable autocomplete attribute for login form (#1485211)
- Check PERMANENTFLAGS before saving $MDNSent flag (#1484963, #1485163)
- Added flag column on messages list (#1484623)
- Patched Mail/MimePart.php (http://pear.php.net/bugs/bug.php?id=14232)
- Allow trash/junk subfolders to be purged (#1485085)
- Store compose parameters in session and redirect to a unique URL
- Fixed CRAM-MD5 authentication (#1484819)
- Fixed forwarding messages with one HTML attachment (#1484442)
- Fixed encoding of message/rfc822 attachments and image/pjpeg handling (#1484914)
- Added option to select skin in user preferences
- Added option to configure displaying of attached images below the message body
- Added option to display images in messages from known senders (#1484601)
- User preferences grouped in more fieldsets
- Fix corrupted MIME headers of messages in Sent folder (#1485111)
- Fixed bug in MDB2 package: http://pear.php.net/bugs/bug.php?id=14124
- Use keypress instead of keydown to select list's row (#1484816)
- Don't call expunge and don't remove message row after message move if flag_for_deletion is set to true (#1485002)
RELEASE 0.2-ALPHA
-----------------
- Added option to disable autocompletion from selected LDAP address books (#1484922)
- TLS support in LDAP connections: 'use_tls' property (#1485104)
- Fixed removing messages from search set after deleting them (#1485106)
- imap.inc: Fixed iil_C_FetchStructureString() to handle many
literal strings in response (#1484969)
- Support for subfolders in default/protected folders (#1484665)
- Disallowed delimiter in folder name (#1484803)
- Support " and \ in folder names
- Escape \ in login (#1484614)
- Better HTML sanitization with the DOM-based washtml script (#1484701)
- Fixed sorting of folders with non-ascii characters
- Fixed Mysql DDL for default identities creation (#1485070)
- In Preferences added possibility to configure 'read_when_deleted',
'mdn_requests', 'flag_for_deletion' options
- Made IMAP auth type configurable (#1483825)
- Fixed empty values with FROM_UNIXTIME() in rcube_mdb2 (#1485055)
- Fixed attachment list on IE 6/7 (#1484807)
- Fixed JavaScript in compose.html that shows cc/bcc fields if populated
- Make password input fields of type password in installer (#1484886)
- Don't attempt to delete cache entries if enable_caching is FALSE (#1485051)
- Optimized messages sorting on servers without sort capability (#1485049)
- Corrected message headers decoding when charset isn't specified and improved
support for native languages (#1485050, #1485048)
- Expanded LDAP configuration options to support LDAP server writes.
- Installer: encode special characters in DB username/password (#1485042)
- Fixed management of folders with national characters in names (#1485036, #1485001)
- Fixed identities saving when using MDB2 pgsql driver (#1485032)
- Fixed BCC header reset (#1484997)
- Improved messages list performance - patch from Justin Heesemann
- Append skin_path to images location only when it starts with '/' sign (#1484859)
- Fix IMAP response in message body when message has no body (#1484964)
- Fixed non-RFC dates formatting (#1484901)
- Fixed typo in set_charset() (#1484991)
- Decode entities when inserting HTML signature to plain text message (#1484990)
- HTML editing is now working with PHP5 updates and TinyMCE v3.0.6
- Fixed signature loading on Windows (#1484545)
- Added language support to HTML editing (#1484862)
- Fixed remove signature when replying (#1333167)
- Fixed problem with line with a space at the end (#1484916)
- Fixed <!DOCTYPE> tag filtering (#1484391)
- Fixed <?xml> tag filtering (#1484403)
- Added sections (fieldset+label) in Settings interface
- Mark as read in one action with message preview (#1484972)
- Deleted redundant quota reads (#1484972)
- Added options for empty trash and expunge inbox on logout (#1483863)
- Removed lines wrapping when displaying message
- Fixed month localization
- Changed codebase to PHP5 with autoloader
RELEASE 0.1.1
-------------
- Clear selection when selecting single item (#1484942)
- Remove hard-coded image size in skin templates (#1484893)
- Database schema improvements (dropped unnecessary indexes)
- Fixed creating a new folder with a comma in its name (#1484681)
- Fixed sorting of messages when default mailbox is empty (#1484317)
- Improve message previewpane - less loading (#1484316)
- Fixed login form autoompletion (#1484839)
- Fixed virtuser_query option for mdb2 backend (#1484874)
- Fixed attachment resoting from Drafts when message body was empty (#1484506)
- Fixed usage of ob_gzhandler (#1484851)
- Fixed message part window in IE6 (#1484610)
- Fixed decoding of mime-encoded strings (#1484191)
- Fixed some iconv/mb_string problems (#1484598)
- Correctly quote mailbox name when using in URL (#1484313)
- Fixed "headers already sent" errors (#1484860)
RELEASE 0.1-STABLE
------------------
- Added interactive installer script
- Fix folder adding/renaming inspired by #1484800
- Localize folder name in page title (#1484785)
- Fix code using wrong variable name (#1484018)
- Allow to send mail with BCC recipients only
- condense TinyMCE toolbar down to one line, removing table buttons (#1484747)
- Add function to mark the selected messages as read/unread (#1457360)
- Also do charset decoding as suggested in RFC 2231 (fix #1484321)
- Show message count in folder list and hint when creating a subfolder
- Distinguish ssl and tls for imap connections (#1484667)
- Added some charset aliases to fix typical mis-labelling (#1484565)
- Remember decision to display images for a certain message during session (#1484754)
- Truncate attachment filenames to 55 characters due to an IE bug (#1484757)
- Make sending of read receipts configurable
- Respect config when localize folder names (#1484707)
- Also respect receipt and priority settings when re-opening a draft message
- Remember search results (closes #1483883), patch by the_glu
- Add Received header on outgoing mail
- Upgrade to TinyMCE 2.1.3
- Allow inserting image attachments into HTML messages while composing (#1484557)
- Implement Message-Disposition-Notification (Receipts)
- Fix overriding of session vars when register_globals is on (#1484670)
- Fix bug with case-sensitive folder names (#1484245)
- Don't create default folders by default
- Fixed some potential security risks (audited by Andris)
- Only show new messages if they match the current search (#1484176)
- Switch to/from when searcing in Sent folder (#1484555)
- Correctly read the References header (#1484646)
- Unset old cookie before sending a new value (#1484639)
- Correctly decode attachments when downloading them (#1484645 and #1484642)
- Suppress IE errors when clearing attachments form (#1484356)
- Log error when login fails due to auto_create_user turned off
- Filter linked/imported CSS files (closes #1484056)
- Improve message compose screen (closes #1484383)
- Select next row after removing one from list (#1484387)
RELEASE 0.1-RC2
---------------
- Enable drag-&-dropping of folders to a new parent and allow to create subfolders (#1457344)
- Suppress IE errors when clearing attachments form (#1484356)
- Set preferences field in user table to NULL (#1484386)
- Log error when login fails due to auto_create_user turned off
- Filter linked/imported CSS files (closes #1484056)
- Improve message compose screen (closes #1484383)
- Select next row after removing one from list (#1484387)
- Make smtp HELO/EHLO hostname configurable (#1484067)
- IPv6 Compatability (#1484322), Patch #1484373
- Unlock interface when message sending fails (#1484570)
- Eval PHP code in template includes (if configured)
- Show message when folder is empty. Mo more static text in table (#1484395)
- Only display unread count in page title when new messages arrived
- Fixed wrong delete button tooltip (#1483965)
- Fixed charset encoding bug (#1484429)
- Applied patch for LDAP version (#1484552)
- Improved XHTML validation
- Fix message list selection (#1484550)
- Better fix lowercased usernames (#1484473)
- Update pngbehavior Script as suggested in #1484490
- Fixed moving/deleting messages when more than 1 is selected
- Applied patch for LDAP contacts listing by Glen Ogilvie
- Applied patch for more address fields in LDAP contacts (#1484402)
- Add alternative for getallheaders() (fix #1484508)
- Identify mailboxes case-sensitive
- Sort mailbox list case-insensitive (closes #1484338)
- Fix display of multipart messages from Apple Mail (closes #1484027)
- Protect AJAX request from being fetched by a foreign site (XSS)
- Make autocomplete for loginform configurable by the skin template
- Fix compose function from address book (closes #1484426)
- Added //IGNORE to iconv call (patch #1484420, closes #1484023)
- Check if mbstring supports charset (#1484290 and #1484292)
- Prefer iconv over mbstring (as suggested in #1484292)
- Check filesize of template includes (#1484409)
- Fixed bug with buttons not dimming/enabling properly after switching folders
- Fixed compose window becoming unresponsive after saving a draft (#1484487)
- Re-enabled "Back" button in compose window now that bug #1484487 is fixed
- Fixed unresponsive interface issue when downloading attachments (#1484496)
- Lowered status message time from 5 to 3 seconds to improve responsiveness
- Raised .htaccess upload_max_filesize from 2M to 5M to differ from default php.ini
- Increased "mailboxcontrols" mail.css width from 160 to 170px to fix non-english languages (#1484499)
- Fix status message bug #1484464 with regard to #1484353
- Fix address adding bug reported by David Koblas
- Applied socket error patch by Thomas Mangin
- Pass-by-reference workarround for PHP5 in sendmail.inc
- Fixed buggy imap_root settings (closes #1484379)
- Prevent default events on subject links (#1484399)
- Use HTTP-POST requests for actions that change state
RELEASE 0.1-RC1
---------------
- Use global filters and bind username/ for Ldap searches (#1484159)
- Hide quota display if imap server does not support it
- Hide address groups if no LDAP servers configured
- Add link to message subjects (closes #1484257)
- Better SQL query for contact listing/search (closes #1484369)
- Fixed marking as read in preview pane (closes #1484364)
- CSS hack to display attachments correctly in IE6
- Wrap message body text (closes #1484148)
- LDAP access is back in address book (closes #1484087)
- Added search function for contacts
- New Template parsing and output encoding
- Fixed bugs #1484119 and #1483978
- Fixed message moving procedure (closes #1484308)
- Fixed display of multiple attachments (closes #1466563)
- Fixed check for new messages (closes #1484310)
- List attachments without filename
- New session authentication: Change sessid cookie when login, authentication with sessauth cookie is now configurable.
Should close bugs #1483951 and #1484299
- Correctly translate mailbox names (closes #1484276)
- Quote e-mail address links (closes #1484300)
- Updated PEAR::Mail_mime package
- Accept single quotes for HTML attributes when modifying message body (thanks Jason)
- Sanitize input for new users/identities (thanks Colin Alston)
- Don't download HTML message parts
- Convert HTML parts to plaintext if 'prefer_html' is off
- Correctly parse message/rfc822 parts (closes #1484045)
- Also use user_id for unique key in messages table (closes #1484074)
- Hide contacts drop down on blur (closes #1484203)
- Make entries in contacts drop down clickable
- Turn off browser autocompletion on login page
- Quote <? in text/html message parts
- Hide border around radio buttons
- Applied patch for attachment download by crichardson (closes #1484198)
- Fixed bug in Postgres DB handling (closes #1484068)
- Fixed bug of invalid calls to fetchRow() in rcube_db.inc (closes #1484280)
- Fixed array_merge bug (closes #1484281)
- Fixed flag for deletion in list view (closes #1484264)
- Finally support semicolons as recipient separator (closes ##1484251)
- Fixed message headers (subject) encoding
- check if safe mode is on or not (closes #1484269)
- Show "no subject" in message list if subject is missing (closes #1484243)
- Solved page caching of message preview (closes #1484153)
- Only use gzip compression if configured (closes #1484236)
- Fixed priority selector issue (#1484150)
- Fixed some CSS issues in default skin (closes #1484210 and #1484161)
- Prevent from double quoting of numeric HTML character references (closes #1484253)
- Fixed display of HTML message attachments (closes #1484178)
- Applied patch for preview caching (closes #1484186)
- Added error handling for attachment uploads
- Use multibyte safe string functions where necessary (closes #1483988)
- Applied security patch to validate the submitted host value (by Kees Cook)
- Applied security patch to validate input values when deleting contacts (by Kees Cook)
- Applied security patch that sanitizes emoticon paths when attaching them (by Kees Cook)
- Applied a patch to more aggressively sanitize a HTML message
- Visualize blocked images in HTML messages
- Fixed wrong message listing when showing search results (closes #1484131)
- Show remote images when opening HTML message part as attachment
- Improve memory usage when sending mail (closes #1484098)
- Mark messages as read once the preview is loaded (closes #1484132)
- Include smtp final response in log (closes #1484081)
- Corrected date string in sent message header (closes #1484125)
- Correclty choose "To" column in sent and draft mailboxes (closes #1483943)
- Changed srong tooltips for message browse buttons (closes #1483930)
- Fixed signature delimeter character to be standard (Bug #1484035)
- Fixed XSS vulnerability (Bug #1484109)
- Remove newlines from mail headers (Bug #1484031)
- Selection issues when moving/deleting (Bug #1484044)
- Applied patch of Clement Moulin for imap host auto-selection
- ISO-encode IMAP password for plaintext login (Bugs #1483977 & #1483886)
- Fixed folder name encoding in subscription list (Bug #1484113)
- Fixed JS errors in identity list (Bug #1484120)
- Translate foldernames in folder form (closes #1484113)
- Added first and last buttons to message list, address book
and message detail
- Pressing Shift-Del bypasses Trash folder
- Enable purge command for Junk folder
- Fetch all aliases if virtuser_query is used instead
- Re-enabled multi select of contacts (Bug #1484017)
- Enable contact editing right after creation (Bug #1459641)
- Correct UTF-7 to UTF-8 conversion if mbstring is not available
- Fixed IMAP fetch of message body (Bug #1484019)
- Fixed safe_mode problems (Bug #1418381)
- Fixed wrong header encoding (Bug #1483976)
- Made automatic draft saving configurable
- Fixed JS bug when renaming folders (Bug #1483989)
- Added quota display as image (by Brett Patterson)
- Corrected creation of a message-id
- New indentation for quoted message text
- Improved HTML validity
- Fixed URL character set (Ticket #1445501)
- Fixed saving of contact into MySQL from LDAP query results (Ticket #1483820)
- Fixed folder renaming: unsubscribe before rename (Bug #1483920)
- Finalized new message parsing (+ chaching)
- Fixed wrong usage of mbstring (Bug #1462439)
- Set default spelling language (Ticket #1483938)
- Added support for Nox Spell Server
- Re-built message parsing (Bug #1327068)
Now based on the message structure delivered by the IMAP server.
- Fixed some XSS and SQL injection issues
- Fixed charset problems with folder renaming
diff --git a/program/lib/Net/IDNA2.php b/program/lib/Net/IDNA2.php
index 0c5f3526b..8c366fb8a 100644
--- a/program/lib/Net/IDNA2.php
+++ b/program/lib/Net/IDNA2.php
@@ -1,3298 +1,3402 @@
<?php
// {{{ license
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
//
// +----------------------------------------------------------------------+
// | This library is free software; you can redistribute it and/or modify |
// | it under the terms of the GNU Lesser General Public License as |
// | published by the Free Software Foundation; either version 2.1 of the |
// | License, or (at your option) any later version. |
// | |
// | This library is distributed in the hope that it will be useful, but |
// | WITHOUT ANY WARRANTY; without even the implied warranty of |
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
// | Lesser General Public License for more details. |
// | |
// | You should have received a copy of the GNU Lesser General Public |
// | License along with this library; if not, write to the Free Software |
// | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
// | USA. |
// +----------------------------------------------------------------------+
//
// }}}
require_once 'Net/IDNA2/Exception.php';
require_once 'Net/IDNA2/Exception/Nameprep.php';
/**
* Encode/decode Internationalized Domain Names.
*
* The class allows to convert internationalized domain names
* (see RFC 3490 for details) as they can be used with various registries worldwide
* to be translated between their original (localized) form and their encoded form
* as it will be used in the DNS (Domain Name System).
*
* The class provides two public methods, encode() and decode(), which do exactly
* what you would expect them to do. You are allowed to use complete domain names,
* simple strings and complete email addresses as well. That means, that you might
* use any of the following notations:
*
* - www.n�rgler.com
* - xn--nrgler-wxa
* - xn--brse-5qa.xn--knrz-1ra.info
*
* Unicode input might be given as either UTF-8 string, UCS-4 string or UCS-4
* array. Unicode output is available in the same formats.
* You can select your preferred format via {@link set_paramter()}.
*
* ACE input and output is always expected to be ASCII.
*
+ * @package Net
* @author Markus Nix <mnix@docuverse.de>
* @author Matthias Sommerfeld <mso@phlylabs.de>
* @author Stefan Neufeind <pear.neufeind@speedpartner.de>
- * @package Net
- * @version $Id: IDNA2.php 301175 2010-07-12 03:31:17Z clockwerx $
+ * @version $Id: IDNA2.php 305344 2010-11-14 23:52:42Z neufeind $
*/
class Net_IDNA2
{
// {{{ npdata
/**
* These Unicode codepoints are
* mapped to nothing, See RFC3454 for details
*
* @static
* @var array
* @access private
*/
private static $_np_map_nothing = array(
0xAD,
0x34F,
0x1806,
0x180B,
0x180C,
0x180D,
0x200B,
0x200C,
0x200D,
0x2060,
0xFE00,
0xFE01,
0xFE02,
0xFE03,
0xFE04,
0xFE05,
0xFE06,
0xFE07,
0xFE08,
0xFE09,
0xFE0A,
0xFE0B,
0xFE0C,
0xFE0D,
0xFE0E,
0xFE0F,
0xFEFF
);
/**
* Prohibited codepints
*
* @static
* @var array
* @access private
*/
private static $_general_prohibited = array(
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
0xA,
0xB,
0xC,
0xD,
0xE,
0xF,
0x10,
0x11,
0x12,
0x13,
0x14,
0x15,
0x16,
0x17,
0x18,
0x19,
0x1A,
0x1B,
0x1C,
0x1D,
0x1E,
0x1F,
0x20,
0x21,
0x22,
0x23,
0x24,
0x25,
0x26,
0x27,
0x28,
0x29,
0x2A,
0x2B,
0x2C,
0x2F,
0x3B,
0x3C,
0x3D,
0x3E,
0x3F,
0x40,
0x5B,
0x5C,
0x5D,
0x5E,
0x5F,
0x60,
0x7B,
0x7C,
0x7D,
0x7E,
0x7F,
0x3002
);
/**
* Codepints prohibited by Nameprep
* @static
* @var array
* @access private
*/
private static $_np_prohibit = array(
0xA0,
0x1680,
0x2000,
0x2001,
0x2002,
0x2003,
0x2004,
0x2005,
0x2006,
0x2007,
0x2008,
0x2009,
0x200A,
0x200B,
0x202F,
0x205F,
0x3000,
0x6DD,
0x70F,
0x180E,
0x200C,
0x200D,
0x2028,
0x2029,
0xFEFF,
0xFFF9,
0xFFFA,
0xFFFB,
0xFFFC,
0xFFFE,
0xFFFF,
0x1FFFE,
0x1FFFF,
0x2FFFE,
0x2FFFF,
0x3FFFE,
0x3FFFF,
0x4FFFE,
0x4FFFF,
0x5FFFE,
0x5FFFF,
0x6FFFE,
0x6FFFF,
0x7FFFE,
0x7FFFF,
0x8FFFE,
0x8FFFF,
0x9FFFE,
0x9FFFF,
0xAFFFE,
0xAFFFF,
0xBFFFE,
0xBFFFF,
0xCFFFE,
0xCFFFF,
0xDFFFE,
0xDFFFF,
0xEFFFE,
0xEFFFF,
0xFFFFE,
0xFFFFF,
0x10FFFE,
0x10FFFF,
0xFFF9,
0xFFFA,
0xFFFB,
0xFFFC,
0xFFFD,
0x340,
0x341,
0x200E,
0x200F,
0x202A,
0x202B,
0x202C,
0x202D,
0x202E,
0x206A,
0x206B,
0x206C,
0x206D,
0x206E,
0x206F,
0xE0001
);
/**
* Codepoint ranges prohibited by nameprep
*
* @static
* @var array
* @access private
*/
private static $_np_prohibit_ranges = array(
array(0x80, 0x9F ),
array(0x2060, 0x206F ),
array(0x1D173, 0x1D17A ),
array(0xE000, 0xF8FF ),
array(0xF0000, 0xFFFFD ),
array(0x100000, 0x10FFFD),
array(0xFDD0, 0xFDEF ),
array(0xD800, 0xDFFF ),
array(0x2FF0, 0x2FFB ),
array(0xE0020, 0xE007F )
);
/**
* Replacement mappings (casemapping, replacement sequences, ...)
*
* @static
* @var array
* @access private
*/
private static $_np_replacemaps = array(
0x41 => array(0x61),
0x42 => array(0x62),
0x43 => array(0x63),
0x44 => array(0x64),
0x45 => array(0x65),
0x46 => array(0x66),
0x47 => array(0x67),
0x48 => array(0x68),
0x49 => array(0x69),
0x4A => array(0x6A),
0x4B => array(0x6B),
0x4C => array(0x6C),
0x4D => array(0x6D),
0x4E => array(0x6E),
0x4F => array(0x6F),
0x50 => array(0x70),
0x51 => array(0x71),
0x52 => array(0x72),
0x53 => array(0x73),
0x54 => array(0x74),
0x55 => array(0x75),
0x56 => array(0x76),
0x57 => array(0x77),
0x58 => array(0x78),
0x59 => array(0x79),
0x5A => array(0x7A),
0xB5 => array(0x3BC),
0xC0 => array(0xE0),
0xC1 => array(0xE1),
0xC2 => array(0xE2),
0xC3 => array(0xE3),
0xC4 => array(0xE4),
0xC5 => array(0xE5),
0xC6 => array(0xE6),
0xC7 => array(0xE7),
0xC8 => array(0xE8),
0xC9 => array(0xE9),
0xCA => array(0xEA),
0xCB => array(0xEB),
0xCC => array(0xEC),
0xCD => array(0xED),
0xCE => array(0xEE),
0xCF => array(0xEF),
0xD0 => array(0xF0),
0xD1 => array(0xF1),
0xD2 => array(0xF2),
0xD3 => array(0xF3),
0xD4 => array(0xF4),
0xD5 => array(0xF5),
0xD6 => array(0xF6),
0xD8 => array(0xF8),
0xD9 => array(0xF9),
0xDA => array(0xFA),
0xDB => array(0xFB),
0xDC => array(0xFC),
0xDD => array(0xFD),
0xDE => array(0xFE),
0xDF => array(0x73, 0x73),
0x100 => array(0x101),
0x102 => array(0x103),
0x104 => array(0x105),
0x106 => array(0x107),
0x108 => array(0x109),
0x10A => array(0x10B),
0x10C => array(0x10D),
0x10E => array(0x10F),
0x110 => array(0x111),
0x112 => array(0x113),
0x114 => array(0x115),
0x116 => array(0x117),
0x118 => array(0x119),
0x11A => array(0x11B),
0x11C => array(0x11D),
0x11E => array(0x11F),
0x120 => array(0x121),
0x122 => array(0x123),
0x124 => array(0x125),
0x126 => array(0x127),
0x128 => array(0x129),
0x12A => array(0x12B),
0x12C => array(0x12D),
0x12E => array(0x12F),
0x130 => array(0x69, 0x307),
0x132 => array(0x133),
0x134 => array(0x135),
0x136 => array(0x137),
0x139 => array(0x13A),
0x13B => array(0x13C),
0x13D => array(0x13E),
0x13F => array(0x140),
0x141 => array(0x142),
0x143 => array(0x144),
0x145 => array(0x146),
0x147 => array(0x148),
0x149 => array(0x2BC, 0x6E),
0x14A => array(0x14B),
0x14C => array(0x14D),
0x14E => array(0x14F),
0x150 => array(0x151),
0x152 => array(0x153),
0x154 => array(0x155),
0x156 => array(0x157),
0x158 => array(0x159),
0x15A => array(0x15B),
0x15C => array(0x15D),
0x15E => array(0x15F),
0x160 => array(0x161),
0x162 => array(0x163),
0x164 => array(0x165),
0x166 => array(0x167),
0x168 => array(0x169),
0x16A => array(0x16B),
0x16C => array(0x16D),
0x16E => array(0x16F),
0x170 => array(0x171),
0x172 => array(0x173),
0x174 => array(0x175),
0x176 => array(0x177),
0x178 => array(0xFF),
0x179 => array(0x17A),
0x17B => array(0x17C),
0x17D => array(0x17E),
0x17F => array(0x73),
0x181 => array(0x253),
0x182 => array(0x183),
0x184 => array(0x185),
0x186 => array(0x254),
0x187 => array(0x188),
0x189 => array(0x256),
0x18A => array(0x257),
0x18B => array(0x18C),
0x18E => array(0x1DD),
0x18F => array(0x259),
0x190 => array(0x25B),
0x191 => array(0x192),
0x193 => array(0x260),
0x194 => array(0x263),
0x196 => array(0x269),
0x197 => array(0x268),
0x198 => array(0x199),
0x19C => array(0x26F),
0x19D => array(0x272),
0x19F => array(0x275),
0x1A0 => array(0x1A1),
0x1A2 => array(0x1A3),
0x1A4 => array(0x1A5),
0x1A6 => array(0x280),
0x1A7 => array(0x1A8),
0x1A9 => array(0x283),
0x1AC => array(0x1AD),
0x1AE => array(0x288),
0x1AF => array(0x1B0),
0x1B1 => array(0x28A),
0x1B2 => array(0x28B),
0x1B3 => array(0x1B4),
0x1B5 => array(0x1B6),
0x1B7 => array(0x292),
0x1B8 => array(0x1B9),
0x1BC => array(0x1BD),
0x1C4 => array(0x1C6),
0x1C5 => array(0x1C6),
0x1C7 => array(0x1C9),
0x1C8 => array(0x1C9),
0x1CA => array(0x1CC),
0x1CB => array(0x1CC),
0x1CD => array(0x1CE),
0x1CF => array(0x1D0),
0x1D1 => array(0x1D2),
0x1D3 => array(0x1D4),
0x1D5 => array(0x1D6),
0x1D7 => array(0x1D8),
0x1D9 => array(0x1DA),
0x1DB => array(0x1DC),
0x1DE => array(0x1DF),
0x1E0 => array(0x1E1),
0x1E2 => array(0x1E3),
0x1E4 => array(0x1E5),
0x1E6 => array(0x1E7),
0x1E8 => array(0x1E9),
0x1EA => array(0x1EB),
0x1EC => array(0x1ED),
0x1EE => array(0x1EF),
0x1F0 => array(0x6A, 0x30C),
0x1F1 => array(0x1F3),
0x1F2 => array(0x1F3),
0x1F4 => array(0x1F5),
0x1F6 => array(0x195),
0x1F7 => array(0x1BF),
0x1F8 => array(0x1F9),
0x1FA => array(0x1FB),
0x1FC => array(0x1FD),
0x1FE => array(0x1FF),
0x200 => array(0x201),
0x202 => array(0x203),
0x204 => array(0x205),
0x206 => array(0x207),
0x208 => array(0x209),
0x20A => array(0x20B),
0x20C => array(0x20D),
0x20E => array(0x20F),
0x210 => array(0x211),
0x212 => array(0x213),
0x214 => array(0x215),
0x216 => array(0x217),
0x218 => array(0x219),
0x21A => array(0x21B),
0x21C => array(0x21D),
0x21E => array(0x21F),
0x220 => array(0x19E),
0x222 => array(0x223),
0x224 => array(0x225),
0x226 => array(0x227),
0x228 => array(0x229),
0x22A => array(0x22B),
0x22C => array(0x22D),
0x22E => array(0x22F),
0x230 => array(0x231),
0x232 => array(0x233),
0x345 => array(0x3B9),
0x37A => array(0x20, 0x3B9),
0x386 => array(0x3AC),
0x388 => array(0x3AD),
0x389 => array(0x3AE),
0x38A => array(0x3AF),
0x38C => array(0x3CC),
0x38E => array(0x3CD),
0x38F => array(0x3CE),
0x390 => array(0x3B9, 0x308, 0x301),
0x391 => array(0x3B1),
0x392 => array(0x3B2),
0x393 => array(0x3B3),
0x394 => array(0x3B4),
0x395 => array(0x3B5),
0x396 => array(0x3B6),
0x397 => array(0x3B7),
0x398 => array(0x3B8),
0x399 => array(0x3B9),
0x39A => array(0x3BA),
0x39B => array(0x3BB),
0x39C => array(0x3BC),
0x39D => array(0x3BD),
0x39E => array(0x3BE),
0x39F => array(0x3BF),
0x3A0 => array(0x3C0),
0x3A1 => array(0x3C1),
0x3A3 => array(0x3C3),
0x3A4 => array(0x3C4),
0x3A5 => array(0x3C5),
0x3A6 => array(0x3C6),
0x3A7 => array(0x3C7),
0x3A8 => array(0x3C8),
0x3A9 => array(0x3C9),
0x3AA => array(0x3CA),
0x3AB => array(0x3CB),
0x3B0 => array(0x3C5, 0x308, 0x301),
0x3C2 => array(0x3C3),
0x3D0 => array(0x3B2),
0x3D1 => array(0x3B8),
0x3D2 => array(0x3C5),
0x3D3 => array(0x3CD),
0x3D4 => array(0x3CB),
0x3D5 => array(0x3C6),
0x3D6 => array(0x3C0),
0x3D8 => array(0x3D9),
0x3DA => array(0x3DB),
0x3DC => array(0x3DD),
0x3DE => array(0x3DF),
0x3E0 => array(0x3E1),
0x3E2 => array(0x3E3),
0x3E4 => array(0x3E5),
0x3E6 => array(0x3E7),
0x3E8 => array(0x3E9),
0x3EA => array(0x3EB),
0x3EC => array(0x3ED),
0x3EE => array(0x3EF),
0x3F0 => array(0x3BA),
0x3F1 => array(0x3C1),
0x3F2 => array(0x3C3),
0x3F4 => array(0x3B8),
0x3F5 => array(0x3B5),
0x400 => array(0x450),
0x401 => array(0x451),
0x402 => array(0x452),
0x403 => array(0x453),
0x404 => array(0x454),
0x405 => array(0x455),
0x406 => array(0x456),
0x407 => array(0x457),
0x408 => array(0x458),
0x409 => array(0x459),
0x40A => array(0x45A),
0x40B => array(0x45B),
0x40C => array(0x45C),
0x40D => array(0x45D),
0x40E => array(0x45E),
0x40F => array(0x45F),
0x410 => array(0x430),
0x411 => array(0x431),
0x412 => array(0x432),
0x413 => array(0x433),
0x414 => array(0x434),
0x415 => array(0x435),
0x416 => array(0x436),
0x417 => array(0x437),
0x418 => array(0x438),
0x419 => array(0x439),
0x41A => array(0x43A),
0x41B => array(0x43B),
0x41C => array(0x43C),
0x41D => array(0x43D),
0x41E => array(0x43E),
0x41F => array(0x43F),
0x420 => array(0x440),
0x421 => array(0x441),
0x422 => array(0x442),
0x423 => array(0x443),
0x424 => array(0x444),
0x425 => array(0x445),
0x426 => array(0x446),
0x427 => array(0x447),
0x428 => array(0x448),
0x429 => array(0x449),
0x42A => array(0x44A),
0x42B => array(0x44B),
0x42C => array(0x44C),
0x42D => array(0x44D),
0x42E => array(0x44E),
0x42F => array(0x44F),
0x460 => array(0x461),
0x462 => array(0x463),
0x464 => array(0x465),
0x466 => array(0x467),
0x468 => array(0x469),
0x46A => array(0x46B),
0x46C => array(0x46D),
0x46E => array(0x46F),
0x470 => array(0x471),
0x472 => array(0x473),
0x474 => array(0x475),
0x476 => array(0x477),
0x478 => array(0x479),
0x47A => array(0x47B),
0x47C => array(0x47D),
0x47E => array(0x47F),
0x480 => array(0x481),
0x48A => array(0x48B),
0x48C => array(0x48D),
0x48E => array(0x48F),
0x490 => array(0x491),
0x492 => array(0x493),
0x494 => array(0x495),
0x496 => array(0x497),
0x498 => array(0x499),
0x49A => array(0x49B),
0x49C => array(0x49D),
0x49E => array(0x49F),
0x4A0 => array(0x4A1),
0x4A2 => array(0x4A3),
0x4A4 => array(0x4A5),
0x4A6 => array(0x4A7),
0x4A8 => array(0x4A9),
0x4AA => array(0x4AB),
0x4AC => array(0x4AD),
0x4AE => array(0x4AF),
0x4B0 => array(0x4B1),
0x4B2 => array(0x4B3),
0x4B4 => array(0x4B5),
0x4B6 => array(0x4B7),
0x4B8 => array(0x4B9),
0x4BA => array(0x4BB),
0x4BC => array(0x4BD),
0x4BE => array(0x4BF),
0x4C1 => array(0x4C2),
0x4C3 => array(0x4C4),
0x4C5 => array(0x4C6),
0x4C7 => array(0x4C8),
0x4C9 => array(0x4CA),
0x4CB => array(0x4CC),
0x4CD => array(0x4CE),
0x4D0 => array(0x4D1),
0x4D2 => array(0x4D3),
0x4D4 => array(0x4D5),
0x4D6 => array(0x4D7),
0x4D8 => array(0x4D9),
0x4DA => array(0x4DB),
0x4DC => array(0x4DD),
0x4DE => array(0x4DF),
0x4E0 => array(0x4E1),
0x4E2 => array(0x4E3),
0x4E4 => array(0x4E5),
0x4E6 => array(0x4E7),
0x4E8 => array(0x4E9),
0x4EA => array(0x4EB),
0x4EC => array(0x4ED),
0x4EE => array(0x4EF),
0x4F0 => array(0x4F1),
0x4F2 => array(0x4F3),
0x4F4 => array(0x4F5),
0x4F8 => array(0x4F9),
0x500 => array(0x501),
0x502 => array(0x503),
0x504 => array(0x505),
0x506 => array(0x507),
0x508 => array(0x509),
0x50A => array(0x50B),
0x50C => array(0x50D),
0x50E => array(0x50F),
0x531 => array(0x561),
0x532 => array(0x562),
0x533 => array(0x563),
0x534 => array(0x564),
0x535 => array(0x565),
0x536 => array(0x566),
0x537 => array(0x567),
0x538 => array(0x568),
0x539 => array(0x569),
0x53A => array(0x56A),
0x53B => array(0x56B),
0x53C => array(0x56C),
0x53D => array(0x56D),
0x53E => array(0x56E),
0x53F => array(0x56F),
0x540 => array(0x570),
0x541 => array(0x571),
0x542 => array(0x572),
0x543 => array(0x573),
0x544 => array(0x574),
0x545 => array(0x575),
0x546 => array(0x576),
0x547 => array(0x577),
0x548 => array(0x578),
0x549 => array(0x579),
0x54A => array(0x57A),
0x54B => array(0x57B),
0x54C => array(0x57C),
0x54D => array(0x57D),
0x54E => array(0x57E),
0x54F => array(0x57F),
0x550 => array(0x580),
0x551 => array(0x581),
0x552 => array(0x582),
0x553 => array(0x583),
0x554 => array(0x584),
0x555 => array(0x585),
0x556 => array(0x586),
0x587 => array(0x565, 0x582),
0x1E00 => array(0x1E01),
0x1E02 => array(0x1E03),
0x1E04 => array(0x1E05),
0x1E06 => array(0x1E07),
0x1E08 => array(0x1E09),
0x1E0A => array(0x1E0B),
0x1E0C => array(0x1E0D),
0x1E0E => array(0x1E0F),
0x1E10 => array(0x1E11),
0x1E12 => array(0x1E13),
0x1E14 => array(0x1E15),
0x1E16 => array(0x1E17),
0x1E18 => array(0x1E19),
0x1E1A => array(0x1E1B),
0x1E1C => array(0x1E1D),
0x1E1E => array(0x1E1F),
0x1E20 => array(0x1E21),
0x1E22 => array(0x1E23),
0x1E24 => array(0x1E25),
0x1E26 => array(0x1E27),
0x1E28 => array(0x1E29),
0x1E2A => array(0x1E2B),
0x1E2C => array(0x1E2D),
0x1E2E => array(0x1E2F),
0x1E30 => array(0x1E31),
0x1E32 => array(0x1E33),
0x1E34 => array(0x1E35),
0x1E36 => array(0x1E37),
0x1E38 => array(0x1E39),
0x1E3A => array(0x1E3B),
0x1E3C => array(0x1E3D),
0x1E3E => array(0x1E3F),
0x1E40 => array(0x1E41),
0x1E42 => array(0x1E43),
0x1E44 => array(0x1E45),
0x1E46 => array(0x1E47),
0x1E48 => array(0x1E49),
0x1E4A => array(0x1E4B),
0x1E4C => array(0x1E4D),
0x1E4E => array(0x1E4F),
0x1E50 => array(0x1E51),
0x1E52 => array(0x1E53),
0x1E54 => array(0x1E55),
0x1E56 => array(0x1E57),
0x1E58 => array(0x1E59),
0x1E5A => array(0x1E5B),
0x1E5C => array(0x1E5D),
0x1E5E => array(0x1E5F),
0x1E60 => array(0x1E61),
0x1E62 => array(0x1E63),
0x1E64 => array(0x1E65),
0x1E66 => array(0x1E67),
0x1E68 => array(0x1E69),
0x1E6A => array(0x1E6B),
0x1E6C => array(0x1E6D),
0x1E6E => array(0x1E6F),
0x1E70 => array(0x1E71),
0x1E72 => array(0x1E73),
0x1E74 => array(0x1E75),
0x1E76 => array(0x1E77),
0x1E78 => array(0x1E79),
0x1E7A => array(0x1E7B),
0x1E7C => array(0x1E7D),
0x1E7E => array(0x1E7F),
0x1E80 => array(0x1E81),
0x1E82 => array(0x1E83),
0x1E84 => array(0x1E85),
0x1E86 => array(0x1E87),
0x1E88 => array(0x1E89),
0x1E8A => array(0x1E8B),
0x1E8C => array(0x1E8D),
0x1E8E => array(0x1E8F),
0x1E90 => array(0x1E91),
0x1E92 => array(0x1E93),
0x1E94 => array(0x1E95),
0x1E96 => array(0x68, 0x331),
0x1E97 => array(0x74, 0x308),
0x1E98 => array(0x77, 0x30A),
0x1E99 => array(0x79, 0x30A),
0x1E9A => array(0x61, 0x2BE),
0x1E9B => array(0x1E61),
0x1EA0 => array(0x1EA1),
0x1EA2 => array(0x1EA3),
0x1EA4 => array(0x1EA5),
0x1EA6 => array(0x1EA7),
0x1EA8 => array(0x1EA9),
0x1EAA => array(0x1EAB),
0x1EAC => array(0x1EAD),
0x1EAE => array(0x1EAF),
0x1EB0 => array(0x1EB1),
0x1EB2 => array(0x1EB3),
0x1EB4 => array(0x1EB5),
0x1EB6 => array(0x1EB7),
0x1EB8 => array(0x1EB9),
0x1EBA => array(0x1EBB),
0x1EBC => array(0x1EBD),
0x1EBE => array(0x1EBF),
0x1EC0 => array(0x1EC1),
0x1EC2 => array(0x1EC3),
0x1EC4 => array(0x1EC5),
0x1EC6 => array(0x1EC7),
0x1EC8 => array(0x1EC9),
0x1ECA => array(0x1ECB),
0x1ECC => array(0x1ECD),
0x1ECE => array(0x1ECF),
0x1ED0 => array(0x1ED1),
0x1ED2 => array(0x1ED3),
0x1ED4 => array(0x1ED5),
0x1ED6 => array(0x1ED7),
0x1ED8 => array(0x1ED9),
0x1EDA => array(0x1EDB),
0x1EDC => array(0x1EDD),
0x1EDE => array(0x1EDF),
0x1EE0 => array(0x1EE1),
0x1EE2 => array(0x1EE3),
0x1EE4 => array(0x1EE5),
0x1EE6 => array(0x1EE7),
0x1EE8 => array(0x1EE9),
0x1EEA => array(0x1EEB),
0x1EEC => array(0x1EED),
0x1EEE => array(0x1EEF),
0x1EF0 => array(0x1EF1),
0x1EF2 => array(0x1EF3),
0x1EF4 => array(0x1EF5),
0x1EF6 => array(0x1EF7),
0x1EF8 => array(0x1EF9),
0x1F08 => array(0x1F00),
0x1F09 => array(0x1F01),
0x1F0A => array(0x1F02),
0x1F0B => array(0x1F03),
0x1F0C => array(0x1F04),
0x1F0D => array(0x1F05),
0x1F0E => array(0x1F06),
0x1F0F => array(0x1F07),
0x1F18 => array(0x1F10),
0x1F19 => array(0x1F11),
0x1F1A => array(0x1F12),
0x1F1B => array(0x1F13),
0x1F1C => array(0x1F14),
0x1F1D => array(0x1F15),
0x1F28 => array(0x1F20),
0x1F29 => array(0x1F21),
0x1F2A => array(0x1F22),
0x1F2B => array(0x1F23),
0x1F2C => array(0x1F24),
0x1F2D => array(0x1F25),
0x1F2E => array(0x1F26),
0x1F2F => array(0x1F27),
0x1F38 => array(0x1F30),
0x1F39 => array(0x1F31),
0x1F3A => array(0x1F32),
0x1F3B => array(0x1F33),
0x1F3C => array(0x1F34),
0x1F3D => array(0x1F35),
0x1F3E => array(0x1F36),
0x1F3F => array(0x1F37),
0x1F48 => array(0x1F40),
0x1F49 => array(0x1F41),
0x1F4A => array(0x1F42),
0x1F4B => array(0x1F43),
0x1F4C => array(0x1F44),
0x1F4D => array(0x1F45),
0x1F50 => array(0x3C5, 0x313),
0x1F52 => array(0x3C5, 0x313, 0x300),
0x1F54 => array(0x3C5, 0x313, 0x301),
0x1F56 => array(0x3C5, 0x313, 0x342),
0x1F59 => array(0x1F51),
0x1F5B => array(0x1F53),
0x1F5D => array(0x1F55),
0x1F5F => array(0x1F57),
0x1F68 => array(0x1F60),
0x1F69 => array(0x1F61),
0x1F6A => array(0x1F62),
0x1F6B => array(0x1F63),
0x1F6C => array(0x1F64),
0x1F6D => array(0x1F65),
0x1F6E => array(0x1F66),
0x1F6F => array(0x1F67),
0x1F80 => array(0x1F00, 0x3B9),
0x1F81 => array(0x1F01, 0x3B9),
0x1F82 => array(0x1F02, 0x3B9),
0x1F83 => array(0x1F03, 0x3B9),
0x1F84 => array(0x1F04, 0x3B9),
0x1F85 => array(0x1F05, 0x3B9),
0x1F86 => array(0x1F06, 0x3B9),
0x1F87 => array(0x1F07, 0x3B9),
0x1F88 => array(0x1F00, 0x3B9),
0x1F89 => array(0x1F01, 0x3B9),
0x1F8A => array(0x1F02, 0x3B9),
0x1F8B => array(0x1F03, 0x3B9),
0x1F8C => array(0x1F04, 0x3B9),
0x1F8D => array(0x1F05, 0x3B9),
0x1F8E => array(0x1F06, 0x3B9),
0x1F8F => array(0x1F07, 0x3B9),
0x1F90 => array(0x1F20, 0x3B9),
0x1F91 => array(0x1F21, 0x3B9),
0x1F92 => array(0x1F22, 0x3B9),
0x1F93 => array(0x1F23, 0x3B9),
0x1F94 => array(0x1F24, 0x3B9),
0x1F95 => array(0x1F25, 0x3B9),
0x1F96 => array(0x1F26, 0x3B9),
0x1F97 => array(0x1F27, 0x3B9),
0x1F98 => array(0x1F20, 0x3B9),
0x1F99 => array(0x1F21, 0x3B9),
0x1F9A => array(0x1F22, 0x3B9),
0x1F9B => array(0x1F23, 0x3B9),
0x1F9C => array(0x1F24, 0x3B9),
0x1F9D => array(0x1F25, 0x3B9),
0x1F9E => array(0x1F26, 0x3B9),
0x1F9F => array(0x1F27, 0x3B9),
0x1FA0 => array(0x1F60, 0x3B9),
0x1FA1 => array(0x1F61, 0x3B9),
0x1FA2 => array(0x1F62, 0x3B9),
0x1FA3 => array(0x1F63, 0x3B9),
0x1FA4 => array(0x1F64, 0x3B9),
0x1FA5 => array(0x1F65, 0x3B9),
0x1FA6 => array(0x1F66, 0x3B9),
0x1FA7 => array(0x1F67, 0x3B9),
0x1FA8 => array(0x1F60, 0x3B9),
0x1FA9 => array(0x1F61, 0x3B9),
0x1FAA => array(0x1F62, 0x3B9),
0x1FAB => array(0x1F63, 0x3B9),
0x1FAC => array(0x1F64, 0x3B9),
0x1FAD => array(0x1F65, 0x3B9),
0x1FAE => array(0x1F66, 0x3B9),
0x1FAF => array(0x1F67, 0x3B9),
0x1FB2 => array(0x1F70, 0x3B9),
0x1FB3 => array(0x3B1, 0x3B9),
0x1FB4 => array(0x3AC, 0x3B9),
0x1FB6 => array(0x3B1, 0x342),
0x1FB7 => array(0x3B1, 0x342, 0x3B9),
0x1FB8 => array(0x1FB0),
0x1FB9 => array(0x1FB1),
0x1FBA => array(0x1F70),
0x1FBB => array(0x1F71),
0x1FBC => array(0x3B1, 0x3B9),
0x1FBE => array(0x3B9),
0x1FC2 => array(0x1F74, 0x3B9),
0x1FC3 => array(0x3B7, 0x3B9),
0x1FC4 => array(0x3AE, 0x3B9),
0x1FC6 => array(0x3B7, 0x342),
0x1FC7 => array(0x3B7, 0x342, 0x3B9),
0x1FC8 => array(0x1F72),
0x1FC9 => array(0x1F73),
0x1FCA => array(0x1F74),
0x1FCB => array(0x1F75),
0x1FCC => array(0x3B7, 0x3B9),
0x1FD2 => array(0x3B9, 0x308, 0x300),
0x1FD3 => array(0x3B9, 0x308, 0x301),
0x1FD6 => array(0x3B9, 0x342),
0x1FD7 => array(0x3B9, 0x308, 0x342),
0x1FD8 => array(0x1FD0),
0x1FD9 => array(0x1FD1),
0x1FDA => array(0x1F76),
0x1FDB => array(0x1F77),
0x1FE2 => array(0x3C5, 0x308, 0x300),
0x1FE3 => array(0x3C5, 0x308, 0x301),
0x1FE4 => array(0x3C1, 0x313),
0x1FE6 => array(0x3C5, 0x342),
0x1FE7 => array(0x3C5, 0x308, 0x342),
0x1FE8 => array(0x1FE0),
0x1FE9 => array(0x1FE1),
0x1FEA => array(0x1F7A),
0x1FEB => array(0x1F7B),
0x1FEC => array(0x1FE5),
0x1FF2 => array(0x1F7C, 0x3B9),
0x1FF3 => array(0x3C9, 0x3B9),
0x1FF4 => array(0x3CE, 0x3B9),
0x1FF6 => array(0x3C9, 0x342),
0x1FF7 => array(0x3C9, 0x342, 0x3B9),
0x1FF8 => array(0x1F78),
0x1FF9 => array(0x1F79),
0x1FFA => array(0x1F7C),
0x1FFB => array(0x1F7D),
0x1FFC => array(0x3C9, 0x3B9),
0x20A8 => array(0x72, 0x73),
0x2102 => array(0x63),
0x2103 => array(0xB0, 0x63),
0x2107 => array(0x25B),
0x2109 => array(0xB0, 0x66),
0x210B => array(0x68),
0x210C => array(0x68),
0x210D => array(0x68),
0x2110 => array(0x69),
0x2111 => array(0x69),
0x2112 => array(0x6C),
0x2115 => array(0x6E),
0x2116 => array(0x6E, 0x6F),
0x2119 => array(0x70),
0x211A => array(0x71),
0x211B => array(0x72),
0x211C => array(0x72),
0x211D => array(0x72),
0x2120 => array(0x73, 0x6D),
0x2121 => array(0x74, 0x65, 0x6C),
0x2122 => array(0x74, 0x6D),
0x2124 => array(0x7A),
0x2126 => array(0x3C9),
0x2128 => array(0x7A),
0x212A => array(0x6B),
0x212B => array(0xE5),
0x212C => array(0x62),
0x212D => array(0x63),
0x2130 => array(0x65),
0x2131 => array(0x66),
0x2133 => array(0x6D),
0x213E => array(0x3B3),
0x213F => array(0x3C0),
0x2145 => array(0x64),
0x2160 => array(0x2170),
0x2161 => array(0x2171),
0x2162 => array(0x2172),
0x2163 => array(0x2173),
0x2164 => array(0x2174),
0x2165 => array(0x2175),
0x2166 => array(0x2176),
0x2167 => array(0x2177),
0x2168 => array(0x2178),
0x2169 => array(0x2179),
0x216A => array(0x217A),
0x216B => array(0x217B),
0x216C => array(0x217C),
0x216D => array(0x217D),
0x216E => array(0x217E),
0x216F => array(0x217F),
0x24B6 => array(0x24D0),
0x24B7 => array(0x24D1),
0x24B8 => array(0x24D2),
0x24B9 => array(0x24D3),
0x24BA => array(0x24D4),
0x24BB => array(0x24D5),
0x24BC => array(0x24D6),
0x24BD => array(0x24D7),
0x24BE => array(0x24D8),
0x24BF => array(0x24D9),
0x24C0 => array(0x24DA),
0x24C1 => array(0x24DB),
0x24C2 => array(0x24DC),
0x24C3 => array(0x24DD),
0x24C4 => array(0x24DE),
0x24C5 => array(0x24DF),
0x24C6 => array(0x24E0),
0x24C7 => array(0x24E1),
0x24C8 => array(0x24E2),
0x24C9 => array(0x24E3),
0x24CA => array(0x24E4),
0x24CB => array(0x24E5),
0x24CC => array(0x24E6),
0x24CD => array(0x24E7),
0x24CE => array(0x24E8),
0x24CF => array(0x24E9),
0x3371 => array(0x68, 0x70, 0x61),
0x3373 => array(0x61, 0x75),
0x3375 => array(0x6F, 0x76),
0x3380 => array(0x70, 0x61),
0x3381 => array(0x6E, 0x61),
0x3382 => array(0x3BC, 0x61),
0x3383 => array(0x6D, 0x61),
0x3384 => array(0x6B, 0x61),
0x3385 => array(0x6B, 0x62),
0x3386 => array(0x6D, 0x62),
0x3387 => array(0x67, 0x62),
0x338A => array(0x70, 0x66),
0x338B => array(0x6E, 0x66),
0x338C => array(0x3BC, 0x66),
0x3390 => array(0x68, 0x7A),
0x3391 => array(0x6B, 0x68, 0x7A),
0x3392 => array(0x6D, 0x68, 0x7A),
0x3393 => array(0x67, 0x68, 0x7A),
0x3394 => array(0x74, 0x68, 0x7A),
0x33A9 => array(0x70, 0x61),
0x33AA => array(0x6B, 0x70, 0x61),
0x33AB => array(0x6D, 0x70, 0x61),
0x33AC => array(0x67, 0x70, 0x61),
0x33B4 => array(0x70, 0x76),
0x33B5 => array(0x6E, 0x76),
0x33B6 => array(0x3BC, 0x76),
0x33B7 => array(0x6D, 0x76),
0x33B8 => array(0x6B, 0x76),
0x33B9 => array(0x6D, 0x76),
0x33BA => array(0x70, 0x77),
0x33BB => array(0x6E, 0x77),
0x33BC => array(0x3BC, 0x77),
0x33BD => array(0x6D, 0x77),
0x33BE => array(0x6B, 0x77),
0x33BF => array(0x6D, 0x77),
0x33C0 => array(0x6B, 0x3C9),
- 0x33C1 => array(0x6D, 0x3C9), /*
- 0x33C2 => array(0x61, 0x2E, 0x6D, 0x2E), */
+ 0x33C1 => array(0x6D, 0x3C9),
+ /* 0x33C2 => array(0x61, 0x2E, 0x6D, 0x2E), */
0x33C3 => array(0x62, 0x71),
0x33C6 => array(0x63, 0x2215, 0x6B, 0x67),
0x33C7 => array(0x63, 0x6F, 0x2E),
0x33C8 => array(0x64, 0x62),
0x33C9 => array(0x67, 0x79),
0x33CB => array(0x68, 0x70),
0x33CD => array(0x6B, 0x6B),
0x33CE => array(0x6B, 0x6D),
0x33D7 => array(0x70, 0x68),
0x33D9 => array(0x70, 0x70, 0x6D),
0x33DA => array(0x70, 0x72),
0x33DC => array(0x73, 0x76),
0x33DD => array(0x77, 0x62),
0xFB00 => array(0x66, 0x66),
0xFB01 => array(0x66, 0x69),
0xFB02 => array(0x66, 0x6C),
0xFB03 => array(0x66, 0x66, 0x69),
0xFB04 => array(0x66, 0x66, 0x6C),
0xFB05 => array(0x73, 0x74),
0xFB06 => array(0x73, 0x74),
0xFB13 => array(0x574, 0x576),
0xFB14 => array(0x574, 0x565),
0xFB15 => array(0x574, 0x56B),
0xFB16 => array(0x57E, 0x576),
0xFB17 => array(0x574, 0x56D),
0xFF21 => array(0xFF41),
0xFF22 => array(0xFF42),
0xFF23 => array(0xFF43),
0xFF24 => array(0xFF44),
0xFF25 => array(0xFF45),
0xFF26 => array(0xFF46),
0xFF27 => array(0xFF47),
0xFF28 => array(0xFF48),
0xFF29 => array(0xFF49),
0xFF2A => array(0xFF4A),
0xFF2B => array(0xFF4B),
0xFF2C => array(0xFF4C),
0xFF2D => array(0xFF4D),
0xFF2E => array(0xFF4E),
0xFF2F => array(0xFF4F),
0xFF30 => array(0xFF50),
0xFF31 => array(0xFF51),
0xFF32 => array(0xFF52),
0xFF33 => array(0xFF53),
0xFF34 => array(0xFF54),
0xFF35 => array(0xFF55),
0xFF36 => array(0xFF56),
0xFF37 => array(0xFF57),
0xFF38 => array(0xFF58),
0xFF39 => array(0xFF59),
0xFF3A => array(0xFF5A),
0x10400 => array(0x10428),
0x10401 => array(0x10429),
0x10402 => array(0x1042A),
0x10403 => array(0x1042B),
0x10404 => array(0x1042C),
0x10405 => array(0x1042D),
0x10406 => array(0x1042E),
0x10407 => array(0x1042F),
0x10408 => array(0x10430),
0x10409 => array(0x10431),
0x1040A => array(0x10432),
0x1040B => array(0x10433),
0x1040C => array(0x10434),
0x1040D => array(0x10435),
0x1040E => array(0x10436),
0x1040F => array(0x10437),
0x10410 => array(0x10438),
0x10411 => array(0x10439),
0x10412 => array(0x1043A),
0x10413 => array(0x1043B),
0x10414 => array(0x1043C),
0x10415 => array(0x1043D),
0x10416 => array(0x1043E),
0x10417 => array(0x1043F),
0x10418 => array(0x10440),
0x10419 => array(0x10441),
0x1041A => array(0x10442),
0x1041B => array(0x10443),
0x1041C => array(0x10444),
0x1041D => array(0x10445),
0x1041E => array(0x10446),
0x1041F => array(0x10447),
0x10420 => array(0x10448),
0x10421 => array(0x10449),
0x10422 => array(0x1044A),
0x10423 => array(0x1044B),
0x10424 => array(0x1044C),
0x10425 => array(0x1044D),
0x1D400 => array(0x61),
0x1D401 => array(0x62),
0x1D402 => array(0x63),
0x1D403 => array(0x64),
0x1D404 => array(0x65),
0x1D405 => array(0x66),
0x1D406 => array(0x67),
0x1D407 => array(0x68),
0x1D408 => array(0x69),
0x1D409 => array(0x6A),
0x1D40A => array(0x6B),
0x1D40B => array(0x6C),
0x1D40C => array(0x6D),
0x1D40D => array(0x6E),
0x1D40E => array(0x6F),
0x1D40F => array(0x70),
0x1D410 => array(0x71),
0x1D411 => array(0x72),
0x1D412 => array(0x73),
0x1D413 => array(0x74),
0x1D414 => array(0x75),
0x1D415 => array(0x76),
0x1D416 => array(0x77),
0x1D417 => array(0x78),
0x1D418 => array(0x79),
0x1D419 => array(0x7A),
0x1D434 => array(0x61),
0x1D435 => array(0x62),
0x1D436 => array(0x63),
0x1D437 => array(0x64),
0x1D438 => array(0x65),
0x1D439 => array(0x66),
0x1D43A => array(0x67),
0x1D43B => array(0x68),
0x1D43C => array(0x69),
0x1D43D => array(0x6A),
0x1D43E => array(0x6B),
0x1D43F => array(0x6C),
0x1D440 => array(0x6D),
0x1D441 => array(0x6E),
0x1D442 => array(0x6F),
0x1D443 => array(0x70),
0x1D444 => array(0x71),
0x1D445 => array(0x72),
0x1D446 => array(0x73),
0x1D447 => array(0x74),
0x1D448 => array(0x75),
0x1D449 => array(0x76),
0x1D44A => array(0x77),
0x1D44B => array(0x78),
0x1D44C => array(0x79),
0x1D44D => array(0x7A),
0x1D468 => array(0x61),
0x1D469 => array(0x62),
0x1D46A => array(0x63),
0x1D46B => array(0x64),
0x1D46C => array(0x65),
0x1D46D => array(0x66),
0x1D46E => array(0x67),
0x1D46F => array(0x68),
0x1D470 => array(0x69),
0x1D471 => array(0x6A),
0x1D472 => array(0x6B),
0x1D473 => array(0x6C),
0x1D474 => array(0x6D),
0x1D475 => array(0x6E),
0x1D476 => array(0x6F),
0x1D477 => array(0x70),
0x1D478 => array(0x71),
0x1D479 => array(0x72),
0x1D47A => array(0x73),
0x1D47B => array(0x74),
0x1D47C => array(0x75),
0x1D47D => array(0x76),
0x1D47E => array(0x77),
0x1D47F => array(0x78),
0x1D480 => array(0x79),
0x1D481 => array(0x7A),
0x1D49C => array(0x61),
0x1D49E => array(0x63),
0x1D49F => array(0x64),
0x1D4A2 => array(0x67),
0x1D4A5 => array(0x6A),
0x1D4A6 => array(0x6B),
0x1D4A9 => array(0x6E),
0x1D4AA => array(0x6F),
0x1D4AB => array(0x70),
0x1D4AC => array(0x71),
0x1D4AE => array(0x73),
0x1D4AF => array(0x74),
0x1D4B0 => array(0x75),
0x1D4B1 => array(0x76),
0x1D4B2 => array(0x77),
0x1D4B3 => array(0x78),
0x1D4B4 => array(0x79),
0x1D4B5 => array(0x7A),
0x1D4D0 => array(0x61),
0x1D4D1 => array(0x62),
0x1D4D2 => array(0x63),
0x1D4D3 => array(0x64),
0x1D4D4 => array(0x65),
0x1D4D5 => array(0x66),
0x1D4D6 => array(0x67),
0x1D4D7 => array(0x68),
0x1D4D8 => array(0x69),
0x1D4D9 => array(0x6A),
0x1D4DA => array(0x6B),
0x1D4DB => array(0x6C),
0x1D4DC => array(0x6D),
0x1D4DD => array(0x6E),
0x1D4DE => array(0x6F),
0x1D4DF => array(0x70),
0x1D4E0 => array(0x71),
0x1D4E1 => array(0x72),
0x1D4E2 => array(0x73),
0x1D4E3 => array(0x74),
0x1D4E4 => array(0x75),
0x1D4E5 => array(0x76),
0x1D4E6 => array(0x77),
0x1D4E7 => array(0x78),
0x1D4E8 => array(0x79),
0x1D4E9 => array(0x7A),
0x1D504 => array(0x61),
0x1D505 => array(0x62),
0x1D507 => array(0x64),
0x1D508 => array(0x65),
0x1D509 => array(0x66),
0x1D50A => array(0x67),
0x1D50D => array(0x6A),
0x1D50E => array(0x6B),
0x1D50F => array(0x6C),
0x1D510 => array(0x6D),
0x1D511 => array(0x6E),
0x1D512 => array(0x6F),
0x1D513 => array(0x70),
0x1D514 => array(0x71),
0x1D516 => array(0x73),
0x1D517 => array(0x74),
0x1D518 => array(0x75),
0x1D519 => array(0x76),
0x1D51A => array(0x77),
0x1D51B => array(0x78),
0x1D51C => array(0x79),
0x1D538 => array(0x61),
0x1D539 => array(0x62),
0x1D53B => array(0x64),
0x1D53C => array(0x65),
0x1D53D => array(0x66),
0x1D53E => array(0x67),
0x1D540 => array(0x69),
0x1D541 => array(0x6A),
0x1D542 => array(0x6B),
0x1D543 => array(0x6C),
0x1D544 => array(0x6D),
0x1D546 => array(0x6F),
0x1D54A => array(0x73),
0x1D54B => array(0x74),
0x1D54C => array(0x75),
0x1D54D => array(0x76),
0x1D54E => array(0x77),
0x1D54F => array(0x78),
0x1D550 => array(0x79),
0x1D56C => array(0x61),
0x1D56D => array(0x62),
0x1D56E => array(0x63),
0x1D56F => array(0x64),
0x1D570 => array(0x65),
0x1D571 => array(0x66),
0x1D572 => array(0x67),
0x1D573 => array(0x68),
0x1D574 => array(0x69),
0x1D575 => array(0x6A),
0x1D576 => array(0x6B),
0x1D577 => array(0x6C),
0x1D578 => array(0x6D),
0x1D579 => array(0x6E),
0x1D57A => array(0x6F),
0x1D57B => array(0x70),
0x1D57C => array(0x71),
0x1D57D => array(0x72),
0x1D57E => array(0x73),
0x1D57F => array(0x74),
0x1D580 => array(0x75),
0x1D581 => array(0x76),
0x1D582 => array(0x77),
0x1D583 => array(0x78),
0x1D584 => array(0x79),
0x1D585 => array(0x7A),
0x1D5A0 => array(0x61),
0x1D5A1 => array(0x62),
0x1D5A2 => array(0x63),
0x1D5A3 => array(0x64),
0x1D5A4 => array(0x65),
0x1D5A5 => array(0x66),
0x1D5A6 => array(0x67),
0x1D5A7 => array(0x68),
0x1D5A8 => array(0x69),
0x1D5A9 => array(0x6A),
0x1D5AA => array(0x6B),
0x1D5AB => array(0x6C),
0x1D5AC => array(0x6D),
0x1D5AD => array(0x6E),
0x1D5AE => array(0x6F),
0x1D5AF => array(0x70),
0x1D5B0 => array(0x71),
0x1D5B1 => array(0x72),
0x1D5B2 => array(0x73),
0x1D5B3 => array(0x74),
0x1D5B4 => array(0x75),
0x1D5B5 => array(0x76),
0x1D5B6 => array(0x77),
0x1D5B7 => array(0x78),
0x1D5B8 => array(0x79),
0x1D5B9 => array(0x7A),
0x1D5D4 => array(0x61),
0x1D5D5 => array(0x62),
0x1D5D6 => array(0x63),
0x1D5D7 => array(0x64),
0x1D5D8 => array(0x65),
0x1D5D9 => array(0x66),
0x1D5DA => array(0x67),
0x1D5DB => array(0x68),
0x1D5DC => array(0x69),
0x1D5DD => array(0x6A),
0x1D5DE => array(0x6B),
0x1D5DF => array(0x6C),
0x1D5E0 => array(0x6D),
0x1D5E1 => array(0x6E),
0x1D5E2 => array(0x6F),
0x1D5E3 => array(0x70),
0x1D5E4 => array(0x71),
0x1D5E5 => array(0x72),
0x1D5E6 => array(0x73),
0x1D5E7 => array(0x74),
0x1D5E8 => array(0x75),
0x1D5E9 => array(0x76),
0x1D5EA => array(0x77),
0x1D5EB => array(0x78),
0x1D5EC => array(0x79),
0x1D5ED => array(0x7A),
0x1D608 => array(0x61),
0x1D609 => array(0x62),
0x1D60A => array(0x63),
0x1D60B => array(0x64),
0x1D60C => array(0x65),
0x1D60D => array(0x66),
0x1D60E => array(0x67),
0x1D60F => array(0x68),
0x1D610 => array(0x69),
0x1D611 => array(0x6A),
0x1D612 => array(0x6B),
0x1D613 => array(0x6C),
0x1D614 => array(0x6D),
0x1D615 => array(0x6E),
0x1D616 => array(0x6F),
0x1D617 => array(0x70),
0x1D618 => array(0x71),
0x1D619 => array(0x72),
0x1D61A => array(0x73),
0x1D61B => array(0x74),
0x1D61C => array(0x75),
0x1D61D => array(0x76),
0x1D61E => array(0x77),
0x1D61F => array(0x78),
0x1D620 => array(0x79),
0x1D621 => array(0x7A),
0x1D63C => array(0x61),
0x1D63D => array(0x62),
0x1D63E => array(0x63),
0x1D63F => array(0x64),
0x1D640 => array(0x65),
0x1D641 => array(0x66),
0x1D642 => array(0x67),
0x1D643 => array(0x68),
0x1D644 => array(0x69),
0x1D645 => array(0x6A),
0x1D646 => array(0x6B),
0x1D647 => array(0x6C),
0x1D648 => array(0x6D),
0x1D649 => array(0x6E),
0x1D64A => array(0x6F),
0x1D64B => array(0x70),
0x1D64C => array(0x71),
0x1D64D => array(0x72),
0x1D64E => array(0x73),
0x1D64F => array(0x74),
0x1D650 => array(0x75),
0x1D651 => array(0x76),
0x1D652 => array(0x77),
0x1D653 => array(0x78),
0x1D654 => array(0x79),
0x1D655 => array(0x7A),
0x1D670 => array(0x61),
0x1D671 => array(0x62),
0x1D672 => array(0x63),
0x1D673 => array(0x64),
0x1D674 => array(0x65),
0x1D675 => array(0x66),
0x1D676 => array(0x67),
0x1D677 => array(0x68),
0x1D678 => array(0x69),
0x1D679 => array(0x6A),
0x1D67A => array(0x6B),
0x1D67B => array(0x6C),
0x1D67C => array(0x6D),
0x1D67D => array(0x6E),
0x1D67E => array(0x6F),
0x1D67F => array(0x70),
0x1D680 => array(0x71),
0x1D681 => array(0x72),
0x1D682 => array(0x73),
0x1D683 => array(0x74),
0x1D684 => array(0x75),
0x1D685 => array(0x76),
0x1D686 => array(0x77),
0x1D687 => array(0x78),
0x1D688 => array(0x79),
0x1D689 => array(0x7A),
0x1D6A8 => array(0x3B1),
0x1D6A9 => array(0x3B2),
0x1D6AA => array(0x3B3),
0x1D6AB => array(0x3B4),
0x1D6AC => array(0x3B5),
0x1D6AD => array(0x3B6),
0x1D6AE => array(0x3B7),
0x1D6AF => array(0x3B8),
0x1D6B0 => array(0x3B9),
0x1D6B1 => array(0x3BA),
0x1D6B2 => array(0x3BB),
0x1D6B3 => array(0x3BC),
0x1D6B4 => array(0x3BD),
0x1D6B5 => array(0x3BE),
0x1D6B6 => array(0x3BF),
0x1D6B7 => array(0x3C0),
0x1D6B8 => array(0x3C1),
0x1D6B9 => array(0x3B8),
0x1D6BA => array(0x3C3),
0x1D6BB => array(0x3C4),
0x1D6BC => array(0x3C5),
0x1D6BD => array(0x3C6),
0x1D6BE => array(0x3C7),
0x1D6BF => array(0x3C8),
0x1D6C0 => array(0x3C9),
0x1D6D3 => array(0x3C3),
0x1D6E2 => array(0x3B1),
0x1D6E3 => array(0x3B2),
0x1D6E4 => array(0x3B3),
0x1D6E5 => array(0x3B4),
0x1D6E6 => array(0x3B5),
0x1D6E7 => array(0x3B6),
0x1D6E8 => array(0x3B7),
0x1D6E9 => array(0x3B8),
0x1D6EA => array(0x3B9),
0x1D6EB => array(0x3BA),
0x1D6EC => array(0x3BB),
0x1D6ED => array(0x3BC),
0x1D6EE => array(0x3BD),
0x1D6EF => array(0x3BE),
0x1D6F0 => array(0x3BF),
0x1D6F1 => array(0x3C0),
0x1D6F2 => array(0x3C1),
0x1D6F3 => array(0x3B8),
0x1D6F4 => array(0x3C3),
0x1D6F5 => array(0x3C4),
0x1D6F6 => array(0x3C5),
0x1D6F7 => array(0x3C6),
0x1D6F8 => array(0x3C7),
0x1D6F9 => array(0x3C8),
0x1D6FA => array(0x3C9),
0x1D70D => array(0x3C3),
0x1D71C => array(0x3B1),
0x1D71D => array(0x3B2),
0x1D71E => array(0x3B3),
0x1D71F => array(0x3B4),
0x1D720 => array(0x3B5),
0x1D721 => array(0x3B6),
0x1D722 => array(0x3B7),
0x1D723 => array(0x3B8),
0x1D724 => array(0x3B9),
0x1D725 => array(0x3BA),
0x1D726 => array(0x3BB),
0x1D727 => array(0x3BC),
0x1D728 => array(0x3BD),
0x1D729 => array(0x3BE),
0x1D72A => array(0x3BF),
0x1D72B => array(0x3C0),
0x1D72C => array(0x3C1),
0x1D72D => array(0x3B8),
0x1D72E => array(0x3C3),
0x1D72F => array(0x3C4),
0x1D730 => array(0x3C5),
0x1D731 => array(0x3C6),
0x1D732 => array(0x3C7),
0x1D733 => array(0x3C8),
0x1D734 => array(0x3C9),
0x1D747 => array(0x3C3),
0x1D756 => array(0x3B1),
0x1D757 => array(0x3B2),
0x1D758 => array(0x3B3),
0x1D759 => array(0x3B4),
0x1D75A => array(0x3B5),
0x1D75B => array(0x3B6),
0x1D75C => array(0x3B7),
0x1D75D => array(0x3B8),
0x1D75E => array(0x3B9),
0x1D75F => array(0x3BA),
0x1D760 => array(0x3BB),
0x1D761 => array(0x3BC),
0x1D762 => array(0x3BD),
0x1D763 => array(0x3BE),
0x1D764 => array(0x3BF),
0x1D765 => array(0x3C0),
0x1D766 => array(0x3C1),
0x1D767 => array(0x3B8),
0x1D768 => array(0x3C3),
0x1D769 => array(0x3C4),
0x1D76A => array(0x3C5),
0x1D76B => array(0x3C6),
0x1D76C => array(0x3C7),
0x1D76D => array(0x3C8),
0x1D76E => array(0x3C9),
0x1D781 => array(0x3C3),
0x1D790 => array(0x3B1),
0x1D791 => array(0x3B2),
0x1D792 => array(0x3B3),
0x1D793 => array(0x3B4),
0x1D794 => array(0x3B5),
0x1D795 => array(0x3B6),
0x1D796 => array(0x3B7),
0x1D797 => array(0x3B8),
0x1D798 => array(0x3B9),
0x1D799 => array(0x3BA),
0x1D79A => array(0x3BB),
0x1D79B => array(0x3BC),
0x1D79C => array(0x3BD),
0x1D79D => array(0x3BE),
0x1D79E => array(0x3BF),
0x1D79F => array(0x3C0),
0x1D7A0 => array(0x3C1),
0x1D7A1 => array(0x3B8),
0x1D7A2 => array(0x3C3),
0x1D7A3 => array(0x3C4),
0x1D7A4 => array(0x3C5),
0x1D7A5 => array(0x3C6),
0x1D7A6 => array(0x3C7),
0x1D7A7 => array(0x3C8),
0x1D7A8 => array(0x3C9),
0x1D7BB => array(0x3C3),
0x3F9 => array(0x3C3),
0x1D2C => array(0x61),
0x1D2D => array(0xE6),
0x1D2E => array(0x62),
0x1D30 => array(0x64),
0x1D31 => array(0x65),
0x1D32 => array(0x1DD),
0x1D33 => array(0x67),
0x1D34 => array(0x68),
0x1D35 => array(0x69),
0x1D36 => array(0x6A),
0x1D37 => array(0x6B),
0x1D38 => array(0x6C),
0x1D39 => array(0x6D),
0x1D3A => array(0x6E),
0x1D3C => array(0x6F),
0x1D3D => array(0x223),
0x1D3E => array(0x70),
0x1D3F => array(0x72),
0x1D40 => array(0x74),
0x1D41 => array(0x75),
0x1D42 => array(0x77),
0x213B => array(0x66, 0x61, 0x78),
0x3250 => array(0x70, 0x74, 0x65),
0x32CC => array(0x68, 0x67),
0x32CE => array(0x65, 0x76),
0x32CF => array(0x6C, 0x74, 0x64),
0x337A => array(0x69, 0x75),
0x33DE => array(0x76, 0x2215, 0x6D),
0x33DF => array(0x61, 0x2215, 0x6D)
);
/**
* Normalization Combining Classes; Code Points not listed
* got Combining Class 0.
*
* @static
* @var array
* @access private
*/
private static $_np_norm_combcls = array(
0x334 => 1,
0x335 => 1,
0x336 => 1,
0x337 => 1,
0x338 => 1,
0x93C => 7,
0x9BC => 7,
0xA3C => 7,
0xABC => 7,
0xB3C => 7,
0xCBC => 7,
0x1037 => 7,
0x3099 => 8,
0x309A => 8,
0x94D => 9,
0x9CD => 9,
0xA4D => 9,
0xACD => 9,
0xB4D => 9,
0xBCD => 9,
0xC4D => 9,
0xCCD => 9,
0xD4D => 9,
0xDCA => 9,
0xE3A => 9,
0xF84 => 9,
0x1039 => 9,
0x1714 => 9,
0x1734 => 9,
0x17D2 => 9,
0x5B0 => 10,
0x5B1 => 11,
0x5B2 => 12,
0x5B3 => 13,
0x5B4 => 14,
0x5B5 => 15,
0x5B6 => 16,
0x5B7 => 17,
0x5B8 => 18,
0x5B9 => 19,
0x5BB => 20,
0x5Bc => 21,
0x5BD => 22,
0x5BF => 23,
0x5C1 => 24,
0x5C2 => 25,
0xFB1E => 26,
0x64B => 27,
0x64C => 28,
0x64D => 29,
0x64E => 30,
0x64F => 31,
0x650 => 32,
0x651 => 33,
0x652 => 34,
0x670 => 35,
0x711 => 36,
0xC55 => 84,
0xC56 => 91,
0xE38 => 103,
0xE39 => 103,
0xE48 => 107,
0xE49 => 107,
0xE4A => 107,
0xE4B => 107,
0xEB8 => 118,
0xEB9 => 118,
0xEC8 => 122,
0xEC9 => 122,
0xECA => 122,
0xECB => 122,
0xF71 => 129,
0xF72 => 130,
0xF7A => 130,
0xF7B => 130,
0xF7C => 130,
0xF7D => 130,
0xF80 => 130,
0xF74 => 132,
0x321 => 202,
0x322 => 202,
0x327 => 202,
0x328 => 202,
0x31B => 216,
0xF39 => 216,
0x1D165 => 216,
0x1D166 => 216,
0x1D16E => 216,
0x1D16F => 216,
0x1D170 => 216,
0x1D171 => 216,
0x1D172 => 216,
0x302A => 218,
0x316 => 220,
0x317 => 220,
0x318 => 220,
0x319 => 220,
0x31C => 220,
0x31D => 220,
0x31E => 220,
0x31F => 220,
0x320 => 220,
0x323 => 220,
0x324 => 220,
0x325 => 220,
0x326 => 220,
0x329 => 220,
0x32A => 220,
0x32B => 220,
0x32C => 220,
0x32D => 220,
0x32E => 220,
0x32F => 220,
0x330 => 220,
0x331 => 220,
0x332 => 220,
0x333 => 220,
0x339 => 220,
0x33A => 220,
0x33B => 220,
0x33C => 220,
0x347 => 220,
0x348 => 220,
0x349 => 220,
0x34D => 220,
0x34E => 220,
0x353 => 220,
0x354 => 220,
0x355 => 220,
0x356 => 220,
0x591 => 220,
0x596 => 220,
0x59B => 220,
0x5A3 => 220,
0x5A4 => 220,
0x5A5 => 220,
0x5A6 => 220,
0x5A7 => 220,
0x5AA => 220,
0x655 => 220,
0x656 => 220,
0x6E3 => 220,
0x6EA => 220,
0x6ED => 220,
0x731 => 220,
0x734 => 220,
0x737 => 220,
0x738 => 220,
0x739 => 220,
0x73B => 220,
0x73C => 220,
0x73E => 220,
0x742 => 220,
0x744 => 220,
0x746 => 220,
0x748 => 220,
0x952 => 220,
0xF18 => 220,
0xF19 => 220,
0xF35 => 220,
0xF37 => 220,
0xFC6 => 220,
0x193B => 220,
0x20E8 => 220,
0x1D17B => 220,
0x1D17C => 220,
0x1D17D => 220,
0x1D17E => 220,
0x1D17F => 220,
0x1D180 => 220,
0x1D181 => 220,
0x1D182 => 220,
0x1D18A => 220,
0x1D18B => 220,
0x59A => 222,
0x5AD => 222,
0x1929 => 222,
0x302D => 222,
0x302E => 224,
0x302F => 224,
0x1D16D => 226,
0x5AE => 228,
0x18A9 => 228,
0x302B => 228,
0x300 => 230,
0x301 => 230,
0x302 => 230,
0x303 => 230,
0x304 => 230,
0x305 => 230,
0x306 => 230,
0x307 => 230,
0x308 => 230,
0x309 => 230,
0x30A => 230,
0x30B => 230,
0x30C => 230,
0x30D => 230,
0x30E => 230,
0x30F => 230,
0x310 => 230,
0x311 => 230,
0x312 => 230,
0x313 => 230,
0x314 => 230,
0x33D => 230,
0x33E => 230,
0x33F => 230,
0x340 => 230,
0x341 => 230,
0x342 => 230,
0x343 => 230,
0x344 => 230,
0x346 => 230,
0x34A => 230,
0x34B => 230,
0x34C => 230,
0x350 => 230,
0x351 => 230,
0x352 => 230,
0x357 => 230,
0x363 => 230,
0x364 => 230,
0x365 => 230,
0x366 => 230,
0x367 => 230,
0x368 => 230,
0x369 => 230,
0x36A => 230,
0x36B => 230,
0x36C => 230,
0x36D => 230,
0x36E => 230,
0x36F => 230,
0x483 => 230,
0x484 => 230,
0x485 => 230,
0x486 => 230,
0x592 => 230,
0x593 => 230,
0x594 => 230,
0x595 => 230,
0x597 => 230,
0x598 => 230,
0x599 => 230,
0x59C => 230,
0x59D => 230,
0x59E => 230,
0x59F => 230,
0x5A0 => 230,
0x5A1 => 230,
0x5A8 => 230,
0x5A9 => 230,
0x5AB => 230,
0x5AC => 230,
0x5AF => 230,
0x5C4 => 230,
0x610 => 230,
0x611 => 230,
0x612 => 230,
0x613 => 230,
0x614 => 230,
0x615 => 230,
0x653 => 230,
0x654 => 230,
0x657 => 230,
0x658 => 230,
0x6D6 => 230,
0x6D7 => 230,
0x6D8 => 230,
0x6D9 => 230,
0x6DA => 230,
0x6DB => 230,
0x6DC => 230,
0x6DF => 230,
0x6E0 => 230,
0x6E1 => 230,
0x6E2 => 230,
0x6E4 => 230,
0x6E7 => 230,
0x6E8 => 230,
0x6EB => 230,
0x6EC => 230,
0x730 => 230,
0x732 => 230,
0x733 => 230,
0x735 => 230,
0x736 => 230,
0x73A => 230,
0x73D => 230,
0x73F => 230,
0x740 => 230,
0x741 => 230,
0x743 => 230,
0x745 => 230,
0x747 => 230,
0x749 => 230,
0x74A => 230,
0x951 => 230,
0x953 => 230,
0x954 => 230,
0xF82 => 230,
0xF83 => 230,
0xF86 => 230,
0xF87 => 230,
0x170D => 230,
0x193A => 230,
0x20D0 => 230,
0x20D1 => 230,
0x20D4 => 230,
0x20D5 => 230,
0x20D6 => 230,
0x20D7 => 230,
0x20DB => 230,
0x20DC => 230,
0x20E1 => 230,
0x20E7 => 230,
0x20E9 => 230,
0xFE20 => 230,
0xFE21 => 230,
0xFE22 => 230,
0xFE23 => 230,
0x1D185 => 230,
0x1D186 => 230,
0x1D187 => 230,
0x1D189 => 230,
0x1D188 => 230,
0x1D1AA => 230,
0x1D1AB => 230,
0x1D1AC => 230,
0x1D1AD => 230,
0x315 => 232,
0x31A => 232,
0x302C => 232,
0x35F => 233,
0x362 => 233,
0x35D => 234,
0x35E => 234,
0x360 => 234,
0x361 => 234,
0x345 => 240
);
// }}}
// {{{ properties
/**
* @var string
* @access private
*/
private $_punycode_prefix = 'xn--';
/**
* @access private
*/
private $_invalid_ucs = 0x80000000;
/**
* @access private
*/
private $_max_ucs = 0x10FFFF;
/**
* @var int
* @access private
*/
private $_base = 36;
/**
* @var int
* @access private
*/
private $_tmin = 1;
/**
* @var int
* @access private
*/
private $_tmax = 26;
/**
* @var int
* @access private
*/
private $_skew = 38;
/**
* @var int
* @access private
*/
private $_damp = 700;
/**
* @var int
* @access private
*/
private $_initial_bias = 72;
/**
* @var int
* @access private
*/
private $_initial_n = 0x80;
/**
* @var int
* @access private
*/
private $_slast;
/**
* @access private
*/
private $_sbase = 0xAC00;
/**
* @access private
*/
private $_lbase = 0x1100;
/**
* @access private
*/
private $_vbase = 0x1161;
/**
* @access private
*/
private $_tbase = 0x11a7;
/**
* @var int
* @access private
*/
private $_lcount = 19;
/**
* @var int
* @access private
*/
private $_vcount = 21;
/**
* @var int
* @access private
*/
private $_tcount = 28;
/**
* vcount * tcount
*
* @var int
* @access private
*/
private $_ncount = 588;
/**
* lcount * tcount * vcount
*
* @var int
* @access private
*/
private $_scount = 11172;
/**
* Default encoding for encode()'s input and decode()'s output is UTF-8;
* Other possible encodings are ucs4_string and ucs4_array
* See {@link setParams()} for how to select these
*
* @var bool
* @access private
*/
private $_api_encoding = 'utf8';
/**
* Overlong UTF-8 encodings are forbidden
*
* @var bool
* @access private
*/
private $_allow_overlong = false;
/**
* Behave strict or not
*
* @var bool
* @access private
*/
private $_strict_mode = false;
+ /**
+ * IDNA-version to use
+ *
+ * Values are "2003" and "2008".
+ * Defaults to "2003", since that was the original version and for
+ * compatibility with previous versions of this library.
+ * If you need to encode "new" characters like the German "Eszett",
+ * please switch to 2008 first before encoding.
+ *
+ * @var bool
+ * @access private
+ */
+ private $_version = '2003';
+
/**
* Cached value indicating whether or not mbstring function overloading is
* on for strlen
*
* This is cached for optimal performance.
*
* @var boolean
* @see Net_IDNA2::_byteLength()
*/
private static $_mb_string_overload = null;
// }}}
// {{{ constructor
/**
* Constructor
*
- * @param array $options
+ * @param array $options Options to initialise the object with
+ *
* @access public
* @see setParams()
*/
public function __construct($options = null)
{
$this->_slast = $this->_sbase + $this->_lcount * $this->_vcount * $this->_tcount;
if (is_array($options)) {
$this->setParams($options);
}
// populate mbstring overloading cache if not set
if (self::$_mb_string_overload === null) {
self::$_mb_string_overload = (extension_loaded('mbstring')
&& (ini_get('mbstring.func_overload') & 0x02) === 0x02);
}
}
// }}}
/**
* Sets a new option value. Available options and values:
*
* [utf8 - Use either UTF-8 or ISO-8859-1 as input (true for UTF-8, false
* otherwise); The output is always UTF-8]
* [overlong - Unicode does not allow unnecessarily long encodings of chars,
* to allow this, set this parameter to true, else to false;
* default is false.]
* [strict - true: strict mode, good for registration purposes - Causes errors
* on failures; false: loose mode, ideal for "wildlife" applications
* by silently ignoring errors and returning the original input instead]
*
- * @param mixed $option Parameter to set (string: single parameter; array of Parameter => Value pairs)
- * @param string $value Value to use (if parameter 1 is a string)
- * @return boolean true on success, false otherwise
- * @access public
+ * @param mixed $option Parameter to set (string: single parameter; array of Parameter => Value pairs)
+ * @param string $value Value to use (if parameter 1 is a string)
+ *
+ * @return boolean true on success, false otherwise
+ * @access public
*/
public function setParams($option, $value = false)
{
if (!is_array($option)) {
$option = array($option => $value);
}
foreach ($option as $k => $v) {
switch ($k) {
case 'encoding':
switch ($v) {
case 'utf8':
case 'ucs4_string':
case 'ucs4_array':
$this->_api_encoding = $v;
break;
default:
throw new InvalidArgumentException('Set Parameter: Unknown parameter '.$v.' for option '.$k);
}
break;
case 'overlong':
$this->_allow_overlong = ($v) ? true : false;
break;
case 'strict':
$this->_strict_mode = ($v) ? true : false;
break;
+ case 'version':
+ if (in_array($v, array('2003', '2008'))) {
+ $this->_version = $v;
+ } else {
+ throw new InvalidArgumentException('Set Parameter: Invalid parameter '.$v.' for option '.$k);
+ }
+ break;
+
default:
return false;
}
}
return true;
}
/**
* Encode a given UTF-8 domain name.
*
- * @param string $decoded Domain name (UTF-8 or UCS-4)
- * [@param string $encoding Desired input encoding, see {@link set_parameter}]
- * @return string Encoded Domain name (ACE string)
- * @return mixed processed string
- * @throws Exception
- * @access public
+ * @param string $decoded Domain name (UTF-8 or UCS-4)
+ * @param string $one_time_encoding Desired input encoding, see {@link set_parameter}
+ * If not given will use default-encoding
+ *
+ * @return string Encoded Domain name (ACE string)
+ * @return mixed processed string
+ * @throws Exception
+ * @access public
*/
public function encode($decoded, $one_time_encoding = false)
{
// Forcing conversion of input to UCS4 array
// If one time encoding is given, use this, else the objects property
switch (($one_time_encoding) ? $one_time_encoding : $this->_api_encoding) {
case 'utf8':
$decoded = $this->_utf8_to_ucs4($decoded);
break;
case 'ucs4_string':
- $decoded = $this->_ucs4_string_to_ucs4($decoded);
+ $decoded = $this->_ucs4_string_to_ucs4($decoded);
case 'ucs4_array': // No break; before this line. Catch case, but do nothing
- break;
+ break;
default:
throw new InvalidArgumentException('Unsupported input format');
}
// No input, no output, what else did you expect?
if (empty($decoded)) return '';
// Anchors for iteration
$last_begin = 0;
// Output string
$output = '';
foreach ($decoded as $k => $v) {
// Make sure to use just the plain dot
switch($v) {
case 0x3002:
case 0xFF0E:
case 0xFF61:
$decoded[$k] = 0x2E;
// It's right, no break here
// The codepoints above have to be converted to dots anyway
// Stumbling across an anchoring character
case 0x2E:
case 0x2F:
case 0x3A:
case 0x3F:
case 0x40:
// Neither email addresses nor URLs allowed in strict mode
if ($this->_strict_mode) {
- throw new InvalidArgumentException('Neither email addresses nor URLs are allowed in strict mode.');
+ throw new InvalidArgumentException('Neither email addresses nor URLs are allowed in strict mode.');
}
// Skip first char
if ($k) {
$encoded = '';
$encoded = $this->_encode(array_slice($decoded, $last_begin, (($k)-$last_begin)));
if ($encoded) {
$output .= $encoded;
} else {
$output .= $this->_ucs4_to_utf8(array_slice($decoded, $last_begin, (($k)-$last_begin)));
}
$output .= chr($decoded[$k]);
}
$last_begin = $k + 1;
}
}
// Catch the rest of the string
if ($last_begin) {
$inp_len = sizeof($decoded);
$encoded = '';
$encoded = $this->_encode(array_slice($decoded, $last_begin, (($inp_len)-$last_begin)));
if ($encoded) {
$output .= $encoded;
} else {
$output .= $this->_ucs4_to_utf8(array_slice($decoded, $last_begin, (($inp_len)-$last_begin)));
}
return $output;
}
if ($output = $this->_encode($decoded)) {
return $output;
}
return $this->_ucs4_to_utf8($decoded);
}
/**
* Decode a given ACE domain name.
*
- * @param string $encoded Domain name (ACE string)
- * @param string $encoding Desired output encoding, see {@link set_parameter}
- * @return string Decoded Domain name (UTF-8 or UCS-4)
- * @throws Exception
- * @access public
+ * @param string $input Domain name (ACE string)
+ * @param string $one_time_encoding Desired output encoding, see {@link set_parameter}
+ *
+ * @return string Decoded Domain name (UTF-8 or UCS-4)
+ * @throws Exception
+ * @access public
*/
public function decode($input, $one_time_encoding = false)
{
// Optionally set
if ($one_time_encoding) {
switch ($one_time_encoding) {
case 'utf8':
case 'ucs4_string':
case 'ucs4_array':
break;
default:
throw new InvalidArgumentException('Unknown encoding '.$one_time_encoding);
}
}
// Make sure to drop any newline characters around
$input = trim($input);
// Negotiate input and try to determine, wether it is a plain string,
// an email address or something like a complete URL
if (strpos($input, '@')) { // Maybe it is an email address
// No no in strict mode
if ($this->_strict_mode) {
throw new InvalidArgumentException('Only simple domain name parts can be handled in strict mode');
}
list($email_pref, $input) = explode('@', $input, 2);
$arr = explode('.', $input);
foreach ($arr as $k => $v) {
$conv = $this->_decode($v);
if ($conv) $arr[$k] = $conv;
}
$return = $email_pref . '@' . join('.', $arr);
} elseif (preg_match('![:\./]!', $input)) { // Or a complete domain name (with or without paths / parameters)
// No no in strict mode
if ($this->_strict_mode) {
throw new InvalidArgumentException('Only simple domain name parts can be handled in strict mode');
}
$parsed = parse_url($input);
if (isset($parsed['host'])) {
$arr = explode('.', $parsed['host']);
foreach ($arr as $k => $v) {
$conv = $this->_decode($v);
if ($conv) $arr[$k] = $conv;
}
$parsed['host'] = join('.', $arr);
if (isset($parsed['scheme'])) {
$parsed['scheme'] .= (strtolower($parsed['scheme']) == 'mailto') ? ':' : '://';
}
- $return = join('', $parsed);
+ $return = $this->_unparse_url($parsed);
} else { // parse_url seems to have failed, try without it
$arr = explode('.', $input);
foreach ($arr as $k => $v) {
$conv = $this->_decode($v);
if ($conv) $arr[$k] = $conv;
}
$return = join('.', $arr);
}
} else { // Otherwise we consider it being a pure domain name string
$return = $this->_decode($input);
}
// The output is UTF-8 by default, other output formats need conversion here
// If one time encoding is given, use this, else the objects property
switch (($one_time_encoding) ? $one_time_encoding : $this->_api_encoding) {
case 'utf8':
return $return;
break;
case 'ucs4_string':
- return $this->_ucs4_to_ucs4_string($this->_utf8_to_ucs4($return));
- break;
+ return $this->_ucs4_to_ucs4_string($this->_utf8_to_ucs4($return));
+ break;
case 'ucs4_array':
return $this->_utf8_to_ucs4($return);
break;
default:
throw new InvalidArgumentException('Unsupported output format');
}
}
// {{{ private
+ /**
+ * Opposite function to parse_url()
+ *
+ * Inspired by code from comments of php.net-documentation for parse_url()
+ *
+ * @param array $parts_arr parts (strings) as returned by parse_url()
+ *
+ * @return string
+ * @access private
+ */
+ private function _unparse_url($parts_arr)
+ {
+ if (!empty($parts_arr['scheme'])) {
+ $ret_url = $parts_arr['scheme'];
+ }
+ if (!empty($parts_arr['user'])) {
+ $ret_url .= $parts_arr['user'];
+ if (!empty($parts_arr['pass'])) {
+ $ret_url .= ':' . $parts_arr['pass'];
+ }
+ $ret_url .= '@';
+ }
+ $ret_url .= $parts_arr['host'];
+ if (!empty($parts_arr['port'])) {
+ $ret_url .= ':' . $parts_arr['port'];
+ }
+ $ret_url .= $parts_arr['path'];
+ if (!empty($parts_arr['query'])) {
+ $ret_url .= '?' . $parts_arr['query'];
+ }
+ if (!empty($parts_arr['fragment'])) {
+ $ret_url .= '#' . $parts_arr['fragment'];
+ }
+ return $ret_url;
+ }
+
/**
* The actual encoding algorithm.
*
- * @return string
- * @throws Exception
- * @access private
+ * @param string $decoded Decoded string which should be encoded
+ *
+ * @return string Encoded string
+ * @throws Exception
+ * @access private
*/
private function _encode($decoded)
{
// We cannot encode a domain name containing the Punycode prefix
$extract = self::_byteLength($this->_punycode_prefix);
$check_pref = $this->_utf8_to_ucs4($this->_punycode_prefix);
$check_deco = array_slice($decoded, 0, $extract);
if ($check_pref == $check_deco) {
throw new InvalidArgumentException('This is already a punycode string');
}
// We will not try to encode strings consisting of basic code points only
$encodable = false;
foreach ($decoded as $k => $v) {
if ($v > 0x7a) {
$encodable = true;
break;
}
}
if (!$encodable) {
if ($this->_strict_mode) {
throw new InvalidArgumentException('The given string does not contain encodable chars');
}
return false;
}
// Do NAMEPREP
$decoded = $this->_nameprep($decoded);
$deco_len = count($decoded);
// Empty array
if (!$deco_len) {
return false;
}
// How many chars have been consumed
$codecount = 0;
// Start with the prefix; copy it to output
$encoded = $this->_punycode_prefix;
$encoded = '';
// Copy all basic code points to output
for ($i = 0; $i < $deco_len; ++$i) {
$test = $decoded[$i];
// Will match [0-9a-zA-Z-]
if ((0x2F < $test && $test < 0x40)
- || (0x40 < $test && $test < 0x5B)
- || (0x60 < $test && $test <= 0x7B)
- || (0x2D == $test)) {
+ || (0x40 < $test && $test < 0x5B)
+ || (0x60 < $test && $test <= 0x7B)
+ || (0x2D == $test)
+ ) {
$encoded .= chr($decoded[$i]);
$codecount++;
}
}
// All codepoints were basic ones
if ($codecount == $deco_len) {
return $encoded;
}
// Start with the prefix; copy it to output
$encoded = $this->_punycode_prefix . $encoded;
// If we have basic code points in output, add an hyphen to the end
if ($codecount) {
$encoded .= '-';
}
// Now find and encode all non-basic code points
$is_first = true;
$cur_code = $this->_initial_n;
$bias = $this->_initial_bias;
$delta = 0;
while ($codecount < $deco_len) {
// Find the smallest code point >= the current code point and
// remember the last ouccrence of it in the input
for ($i = 0, $next_code = $this->_max_ucs; $i < $deco_len; $i++) {
if ($decoded[$i] >= $cur_code && $decoded[$i] <= $next_code) {
$next_code = $decoded[$i];
}
}
$delta += ($next_code - $cur_code) * ($codecount + 1);
$cur_code = $next_code;
// Scan input again and encode all characters whose code point is $cur_code
for ($i = 0; $i < $deco_len; $i++) {
if ($decoded[$i] < $cur_code) {
$delta++;
} else if ($decoded[$i] == $cur_code) {
for ($q = $delta, $k = $this->_base; 1; $k += $this->_base) {
$t = ($k <= $bias)?
$this->_tmin :
(($k >= $bias + $this->_tmax)? $this->_tmax : $k - $bias);
if ($q < $t) {
break;
}
$encoded .= $this->_encodeDigit(ceil($t + (($q - $t) % ($this->_base - $t))));
$q = ($q - $t) / ($this->_base - $t);
}
$encoded .= $this->_encodeDigit($q);
$bias = $this->_adapt($delta, $codecount + 1, $is_first);
$codecount++;
$delta = 0;
$is_first = false;
}
}
$delta++;
$cur_code++;
}
return $encoded;
}
/**
* The actual decoding algorithm.
*
- * @return string
- * @throws Exception
- * @access private
+ * @param string $encoded Encoded string which should be decoded
+ *
+ * @return string Decoded string
+ * @throws Exception
+ * @access private
*/
private function _decode($encoded)
{
// We do need to find the Punycode prefix
if (!preg_match('!^' . preg_quote($this->_punycode_prefix, '!') . '!', $encoded)) {
return false;
}
$encode_test = preg_replace('!^' . preg_quote($this->_punycode_prefix, '!') . '!', '', $encoded);
// If nothing left after removing the prefix, it is hopeless
if (!$encode_test) {
return false;
}
// Find last occurence of the delimiter
$delim_pos = strrpos($encoded, '-');
if ($delim_pos > self::_byteLength($this->_punycode_prefix)) {
for ($k = self::_byteLength($this->_punycode_prefix); $k < $delim_pos; ++$k) {
$decoded[] = ord($encoded{$k});
}
} else {
$decoded = array();
}
$deco_len = count($decoded);
$enco_len = self::_byteLength($encoded);
// Wandering through the strings; init
$is_first = true;
$bias = $this->_initial_bias;
$idx = 0;
$char = $this->_initial_n;
for ($enco_idx = ($delim_pos)? ($delim_pos + 1) : 0; $enco_idx < $enco_len; ++$deco_len) {
for ($old_idx = $idx, $w = 1, $k = $this->_base; 1 ; $k += $this->_base) {
$digit = $this->_decodeDigit($encoded{$enco_idx++});
$idx += $digit * $w;
$t = ($k <= $bias) ?
$this->_tmin :
(($k >= $bias + $this->_tmax)? $this->_tmax : ($k - $bias));
if ($digit < $t) {
break;
}
$w = (int)($w * ($this->_base - $t));
}
$bias = $this->_adapt($idx - $old_idx, $deco_len + 1, $is_first);
$is_first = false;
$char += (int) ($idx / ($deco_len + 1));
$idx %= ($deco_len + 1);
if ($deco_len > 0) {
// Make room for the decoded char
for ($i = $deco_len; $i > $idx; $i--) {
$decoded[$i] = $decoded[($i - 1)];
}
}
$decoded[$idx++] = $char;
}
return $this->_ucs4_to_utf8($decoded);
}
/**
* Adapt the bias according to the current code point and position.
*
- * @access private
+ * @param int $delta ...
+ * @param int $npoints ...
+ * @param boolean $is_first ...
+ *
+ * @return int
+ * @access private
*/
private function _adapt($delta, $npoints, $is_first)
{
$delta = (int) ($is_first ? ($delta / $this->_damp) : ($delta / 2));
$delta += (int) ($delta / $npoints);
for ($k = 0; $delta > (($this->_base - $this->_tmin) * $this->_tmax) / 2; $k += $this->_base) {
$delta = (int) ($delta / ($this->_base - $this->_tmin));
}
return (int) ($k + ($this->_base - $this->_tmin + 1) * $delta / ($delta + $this->_skew));
}
/**
* Encoding a certain digit.
*
- * @access private
+ * @param int $d One digit to encode
+ *
+ * @return char Encoded digit
+ * @access private
*/
private function _encodeDigit($d)
{
return chr($d + 22 + 75 * ($d < 26));
}
/**
* Decode a certain digit.
*
- * @access private
+ * @param char $cp One digit (character) to decode
+ *
+ * @return int Decoded digit
+ * @access private
*/
private function _decodeDigit($cp)
{
$cp = ord($cp);
return ($cp - 48 < 10)? $cp - 22 : (($cp - 65 < 26)? $cp - 65 : (($cp - 97 < 26)? $cp - 97 : $this->_base));
}
/**
* Do Nameprep according to RFC3491 and RFC3454.
*
- * @param array $input Unicode Characters
- * @return string Unicode Characters, Nameprep'd
- * @throws Exception
- * @access private
+ * @param array $input Unicode Characters
+ *
+ * @return string Unicode Characters, Nameprep'd
+ * @throws Exception
+ * @access private
*/
private function _nameprep($input)
{
$output = array();
// Walking through the input array, performing the required steps on each of
// the input chars and putting the result into the output array
// While mapping required chars we apply the cannonical ordering
foreach ($input as $v) {
// Map to nothing == skip that code point
if (in_array($v, self::$_np_map_nothing)) {
continue;
}
// Try to find prohibited input
if (in_array($v, self::$_np_prohibit) || in_array($v, self::$_general_prohibited)) {
throw new Net_IDNA2_Exception_Nameprep('Prohibited input U+' . sprintf('%08X', $v));
}
foreach (self::$_np_prohibit_ranges as $range) {
if ($range[0] <= $v && $v <= $range[1]) {
throw new Net_IDNA2_Exception_Nameprep('Prohibited input U+' . sprintf('%08X', $v));
}
}
// Hangul syllable decomposition
if (0xAC00 <= $v && $v <= 0xD7AF) {
foreach ($this->_hangulDecompose($v) as $out) {
$output[] = $out;
}
- } else if (isset(self::$_np_replacemaps[$v])) { // There's a decomposition mapping for that code point
+ } else if (($this->_version == '2003') && isset(self::$_np_replacemaps[$v])) {
+ // There's a decomposition mapping for that code point
+ // Decompositions only in version 2003 (original) of IDNA
foreach ($this->_applyCannonicalOrdering(self::$_np_replacemaps[$v]) as $out) {
$output[] = $out;
}
} else {
$output[] = $v;
}
}
// Combine code points
$last_class = 0;
$last_starter = 0;
$out_len = count($output);
for ($i = 0; $i < $out_len; ++$i) {
$class = $this->_getCombiningClass($output[$i]);
if ((!$last_class || $last_class != $class) && $class) {
// Try to match
$seq_len = $i - $last_starter;
$out = $this->_combine(array_slice($output, $last_starter, $seq_len));
// On match: Replace the last starter with the composed character and remove
// the now redundant non-starter(s)
if ($out) {
$output[$last_starter] = $out;
if (count($out) != $seq_len) {
for ($j = $i + 1; $j < $out_len; ++$j) {
$output[$j - 1] = $output[$j];
}
unset($output[$out_len]);
}
// Rewind the for loop by one, since there can be more possible compositions
$i--;
$out_len--;
$last_class = ($i == $last_starter)? 0 : $this->_getCombiningClass($output[$i - 1]);
continue;
}
}
// The current class is 0
if (!$class) {
$last_starter = $i;
}
$last_class = $class;
}
return $output;
}
/**
* Decomposes a Hangul syllable
* (see http://www.unicode.org/unicode/reports/tr15/#Hangul).
*
- * @param integer $char 32bit UCS4 code point
- * @return array Either Hangul Syllable decomposed or original 32bit
- * value as one value array
- * @access private
+ * @param integer $char 32bit UCS4 code point
+ *
+ * @return array Either Hangul Syllable decomposed or original 32bit
+ * value as one value array
+ * @access private
*/
private function _hangulDecompose($char)
{
$sindex = $char - $this->_sbase;
if ($sindex < 0 || $sindex >= $this->_scount) {
return array($char);
}
$result = array();
$T = $this->_tbase + $sindex % $this->_tcount;
$result[] = (int)($this->_lbase + $sindex / $this->_ncount);
$result[] = (int)($this->_vbase + ($sindex % $this->_ncount) / $this->_tcount);
if ($T != $this->_tbase) {
$result[] = $T;
}
return $result;
}
/**
* Ccomposes a Hangul syllable
* (see http://www.unicode.org/unicode/reports/tr15/#Hangul).
*
- * @param array $input Decomposed UCS4 sequence
- * @return array UCS4 sequence with syllables composed
- * @access private
+ * @param array $input Decomposed UCS4 sequence
+ *
+ * @return array UCS4 sequence with syllables composed
+ * @access private
*/
private function _hangulCompose($input)
{
$inp_len = count($input);
if (!$inp_len) {
return array();
}
$result = array();
$last = $input[0];
$result[] = $last; // copy first char from input to output
for ($i = 1; $i < $inp_len; ++$i) {
$char = $input[$i];
// Find out, wether two current characters from L and V
$lindex = $last - $this->_lbase;
if (0 <= $lindex && $lindex < $this->_lcount) {
$vindex = $char - $this->_vbase;
if (0 <= $vindex && $vindex < $this->_vcount) {
// create syllable of form LV
$last = ($this->_sbase + ($lindex * $this->_vcount + $vindex) * $this->_tcount);
$out_off = count($result) - 1;
$result[$out_off] = $last; // reset last
// discard char
continue;
}
}
// Find out, wether two current characters are LV and T
$sindex = $last - $this->_sbase;
if (0 <= $sindex && $sindex < $this->_scount && ($sindex % $this->_tcount) == 0) {
$tindex = $char - $this->_tbase;
if (0 <= $tindex && $tindex <= $this->_tcount) {
// create syllable of form LVT
$last += $tindex;
$out_off = count($result) - 1;
$result[$out_off] = $last; // reset last
// discard char
continue;
}
}
// if neither case was true, just add the character
$last = $char;
$result[] = $char;
}
return $result;
}
/**
* Returns the combining class of a certain wide char.
*
- * @param integer $char Wide char to check (32bit integer)
- * @return integer Combining class if found, else 0
- * @access private
+ * @param integer $char Wide char to check (32bit integer)
+ *
+ * @return integer Combining class if found, else 0
+ * @access private
*/
private function _getCombiningClass($char)
{
return isset(self::$_np_norm_combcls[$char])? self::$_np_norm_combcls[$char] : 0;
}
/**
* Apllies the cannonical ordering of a decomposed UCS4 sequence.
*
- * @param array $input Decomposed UCS4 sequence
- * @return array Ordered USC4 sequence
- * @access private
+ * @param array $input Decomposed UCS4 sequence
+ *
+ * @return array Ordered USC4 sequence
+ * @access private
*/
private function _applyCannonicalOrdering($input)
{
$swap = true;
$size = count($input);
while ($swap) {
$swap = false;
$last = $this->_getCombiningClass($input[0]);
for ($i = 0; $i < $size - 1; ++$i) {
$next = $this->_getCombiningClass($input[$i + 1]);
if ($next != 0 && $last > $next) {
// Move item leftward until it fits
for ($j = $i + 1; $j > 0; --$j) {
if ($this->_getCombiningClass($input[$j - 1]) <= $next) {
break;
}
$t = $input[$j];
$input[$j] = $input[$j - 1];
$input[$j - 1] = $t;
$swap = 1;
}
// Reentering the loop looking at the old character again
$next = $last;
}
$last = $next;
}
}
return $input;
}
/**
* Do composition of a sequence of starter and non-starter.
*
- * @param array $input UCS4 Decomposed sequence
- * @return array Ordered USC4 sequence
- * @access private
+ * @param array $input UCS4 Decomposed sequence
+ *
+ * @return array Ordered USC4 sequence
+ * @access private
*/
private function _combine($input)
{
$inp_len = count($input);
// Is it a Hangul syllable?
if (1 != $inp_len) {
$hangul = $this->_hangulCompose($input);
// This place is probably wrong
if (count($hangul) != $inp_len) {
return $hangul;
}
}
foreach (self::$_np_replacemaps as $np_src => $np_target) {
if ($np_target[0] != $input[0]) {
continue;
}
if (count($np_target) != $inp_len) {
continue;
}
$hit = false;
foreach ($input as $k2 => $v2) {
if ($v2 == $np_target[$k2]) {
$hit = true;
} else {
$hit = false;
break;
}
}
if ($hit) {
return $np_src;
}
}
return false;
}
/**
* This converts an UTF-8 encoded string to its UCS-4 (array) representation
* By talking about UCS-4 we mean arrays of 32bit integers representing
* each of the "chars". This is due to PHP not being able to handle strings with
* bit depth different from 8. This applies to the reverse method _ucs4_to_utf8(), too.
* The following UTF-8 encodings are supported:
*
* bytes bits representation
* 1 7 0xxxxxxx
* 2 11 110xxxxx 10xxxxxx
* 3 16 1110xxxx 10xxxxxx 10xxxxxx
* 4 21 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
* 5 26 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
* 6 31 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
*
* Each x represents a bit that can be used to store character data.
*
- * @access private
+ * @param string $input utf8-encoded string
+ *
+ * @return array ucs4-encoded array
+ * @throws Exception
+ * @access private
*/
private function _utf8_to_ucs4($input)
{
$output = array();
$out_len = 0;
$inp_len = self::_byteLength($input, '8bit');
$mode = 'next';
$test = 'none';
for ($k = 0; $k < $inp_len; ++$k) {
$v = ord($input{$k}); // Extract byte from input string
if ($v < 128) { // We found an ASCII char - put into stirng as is
$output[$out_len] = $v;
++$out_len;
if ('add' == $mode) {
throw new UnexpectedValueException('Conversion from UTF-8 to UCS-4 failed: malformed input at byte '.$k);
}
continue;
}
if ('next' == $mode) { // Try to find the next start byte; determine the width of the Unicode char
$start_byte = $v;
$mode = 'add';
$test = 'range';
if ($v >> 5 == 6) { // &110xxxxx 10xxxxx
$next_byte = 0; // Tells, how many times subsequent bitmasks must rotate 6bits to the left
$v = ($v - 192) << 6;
} elseif ($v >> 4 == 14) { // &1110xxxx 10xxxxxx 10xxxxxx
$next_byte = 1;
$v = ($v - 224) << 12;
} elseif ($v >> 3 == 30) { // &11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
$next_byte = 2;
$v = ($v - 240) << 18;
} elseif ($v >> 2 == 62) { // &111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
$next_byte = 3;
$v = ($v - 248) << 24;
} elseif ($v >> 1 == 126) { // &1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
$next_byte = 4;
$v = ($v - 252) << 30;
} else {
throw new UnexpectedValueException('This might be UTF-8, but I don\'t understand it at byte '.$k);
}
if ('add' == $mode) {
$output[$out_len] = (int) $v;
++$out_len;
continue;
}
}
if ('add' == $mode) {
if (!$this->_allow_overlong && $test == 'range') {
$test = 'none';
if (($v < 0xA0 && $start_byte == 0xE0) || ($v < 0x90 && $start_byte == 0xF0) || ($v > 0x8F && $start_byte == 0xF4)) {
throw new OutOfRangeException('Bogus UTF-8 character detected (out of legal range) at byte '.$k);
}
}
if ($v >> 6 == 2) { // Bit mask must be 10xxxxxx
$v = ($v - 128) << ($next_byte * 6);
$output[($out_len - 1)] += $v;
--$next_byte;
} else {
throw new UnexpectedValueException('Conversion from UTF-8 to UCS-4 failed: malformed input at byte '.$k);
}
if ($next_byte < 0) {
$mode = 'next';
}
}
} // for
return $output;
}
/**
- * Convert UCS-4 array into UTF-8 string.
+ * Convert UCS-4 array into UTF-8 string
*
- * @throws Exception
- * @access private
+ * @param array $input ucs4-encoded array
+ *
+ * @return string utf8-encoded string
+ * @throws Exception
+ * @access private
*/
private function _ucs4_to_utf8($input)
{
$output = '';
foreach ($input as $v) {
// $v = ord($v);
if ($v < 128) {
// 7bit are transferred literally
$output .= chr($v);
} else if ($v < 1 << 11) {
// 2 bytes
$output .= chr(192 + ($v >> 6))
. chr(128 + ($v & 63));
} else if ($v < 1 << 16) {
// 3 bytes
$output .= chr(224 + ($v >> 12))
. chr(128 + (($v >> 6) & 63))
. chr(128 + ($v & 63));
} else if ($v < 1 << 21) {
// 4 bytes
$output .= chr(240 + ($v >> 18))
. chr(128 + (($v >> 12) & 63))
. chr(128 + (($v >> 6) & 63))
. chr(128 + ($v & 63));
} else if ($v < 1 << 26) {
// 5 bytes
$output .= chr(248 + ($v >> 24))
. chr(128 + (($v >> 18) & 63))
. chr(128 + (($v >> 12) & 63))
. chr(128 + (($v >> 6) & 63))
. chr(128 + ($v & 63));
} else if ($v < 1 << 31) {
// 6 bytes
$output .= chr(252 + ($v >> 30))
. chr(128 + (($v >> 24) & 63))
. chr(128 + (($v >> 18) & 63))
. chr(128 + (($v >> 12) & 63))
. chr(128 + (($v >> 6) & 63))
. chr(128 + ($v & 63));
} else {
throw new UnexpectedValueException('Conversion from UCS-4 to UTF-8 failed: malformed input');
}
}
return $output;
}
/**
* Convert UCS-4 array into UCS-4 string
*
- * @throws Exception
- * @access private
+ * @param array $input ucs4-encoded array
+ *
+ * @return string ucs4-encoded string
+ * @throws Exception
+ * @access private
*/
private function _ucs4_to_ucs4_string($input)
{
$output = '';
// Take array values and split output to 4 bytes per value
// The bit mask is 255, which reads &11111111
foreach ($input as $v) {
$output .= ($v & (255 << 24) >> 24) . ($v & (255 << 16) >> 16) . ($v & (255 << 8) >> 8) . ($v & 255);
}
return $output;
}
/**
- * Convert UCS-4 strin into UCS-4 garray
+ * Convert UCS-4 string into UCS-4 array
*
- * @throws InvalidArgumentException
- * @access private
+ * @param string $input ucs4-encoded string
+ *
+ * @return array ucs4-encoded array
+ * @throws InvalidArgumentException
+ * @access private
*/
private function _ucs4_string_to_ucs4($input)
{
$output = array();
$inp_len = self::_byteLength($input);
// Input length must be dividable by 4
if ($inp_len % 4) {
throw new InvalidArgumentException('Input UCS4 string is broken');
}
// Empty input - return empty output
if (!$inp_len) {
return $output;
}
for ($i = 0, $out_len = -1; $i < $inp_len; ++$i) {
// Increment output position every 4 input bytes
if (!$i % 4) {
$out_len++;
$output[$out_len] = 0;
}
$output[$out_len] += ord($input{$i}) << (8 * (3 - ($i % 4) ) );
}
return $output;
}
/**
* Echo hex representation of UCS4 sequence.
*
- * @param array $input UCS4 sequence
- * @param boolean $include_bit Include bitmask in output
- * @return void
+ * @param array $input UCS4 sequence
+ * @param boolean $include_bit Include bitmask in output
+ *
+ * @return void
* @static
- * @access private
+ * @access private
*/
private static function _showHex($input, $include_bit = false)
{
foreach ($input as $k => $v) {
echo '[', $k, '] => ', sprintf('%X', $v);
if ($include_bit) {
echo ' (', Net_IDNA2::_showBitmask($v), ')';
}
echo "\n";
}
}
/**
* Gives you a bit representation of given Byte (8 bits), Word (16 bits) or DWord (32 bits)
* Output width is automagically determined
*
+ * @param int $octet ...
+ *
+ * @return string Bitmask-representation
* @static
- * @access private
+ * @access private
*/
private static function _showBitmask($octet)
{
if ($octet >= (1 << 16)) {
$w = 31;
} else if ($octet >= (1 << 8)) {
$w = 15;
} else {
$w = 7;
}
$return = '';
for ($i = $w; $i > -1; $i--) {
- $return .= ($octet & (1 << $i))? 1 : '0';
+ $return .= ($octet & (1 << $i))? '1' : '0';
}
return $return;
}
/**
* Gets the length of a string in bytes even if mbstring function
* overloading is turned on
*
* @param string $string the string for which to get the length.
*
* @return integer the length of the string in bytes.
*
* @see Net_IDNA2::$_mb_string_overload
*/
private static function _byteLength($string)
{
if (self::$_mb_string_overload) {
return mb_strlen($string, '8bit');
}
return strlen((binary)$string);
}
// }}}}
// {{{ factory
/**
* Attempts to return a concrete IDNA instance for either php4 or php5.
*
* @param array $params Set of paramaters
*
* @return Net_IDNA2
* @access public
*/
function getInstance($params = array())
{
return new Net_IDNA2($params);
}
// }}}
// {{{ singleton
/**
* Attempts to return a concrete IDNA instance for either php4 or php5,
* only creating a new instance if no IDNA instance with the same
* parameters currently exists.
*
* @param array $params Set of paramaters
*
* @return object Net_IDNA2
* @access public
*/
function singleton($params = array())
{
static $instances;
if (!isset($instances)) {
$instances = array();
}
$signature = serialize($params);
if (!isset($instances[$signature])) {
$instances[$signature] = Net_IDNA2::getInstance($params);
}
return $instances[$signature];
}
// }}}
}
?>
diff --git a/program/lib/Net/IDNA2/Exception.php b/program/lib/Net/IDNA2/Exception.php
index 9c77ad6e1..72cb1ae75 100644
--- a/program/lib/Net/IDNA2/Exception.php
+++ b/program/lib/Net/IDNA2/Exception.php
@@ -1,3 +1,4 @@
-<?php
-class Net_IDNA2_Exception extends Exception {
-}
+<?php
+class Net_IDNA2_Exception extends Exception
+{
+}
diff --git a/program/lib/Net/IDNA2/Exception/Nameprep.php b/program/lib/Net/IDNA2/Exception/Nameprep.php
index a753e173d..44cbd6bb9 100644
--- a/program/lib/Net/IDNA2/Exception/Nameprep.php
+++ b/program/lib/Net/IDNA2/Exception/Nameprep.php
@@ -1,5 +1,6 @@
-<?php
-require_once 'Net/IDNA2/Exception.php';
-
-class Net_IDNA2_Exception_Nameprep extends Net_IDNA2_Exception {
-}
\ No newline at end of file
+<?php
+require_once 'Net/IDNA2/Exception.php';
+
+class Net_IDNA2_Exception_Nameprep extends Net_IDNA2_Exception
+{
+}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Dec 18, 1:29 PM (1 d, 15 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
418844
Default Alt Text
(166 KB)
Attached To
Mode
R3 roundcubemail
Attached
Detach File
Event Timeline
Log In to Comment