Skip to content

Commit

Permalink
Backported fix for CORE-1499: Wrong alignment of data, used in INTL c…
Browse files Browse the repository at this point in the history
…onverters
  • Loading branch information
AlexPeshkoff committed Nov 2, 2007
1 parent 7818e74 commit 39fd59d
Show file tree
Hide file tree
Showing 27 changed files with 464 additions and 332 deletions.
115 changes: 115 additions & 0 deletions src/common/classes/Aligner.h
@@ -0,0 +1,115 @@
/*
* PROGRAM: JRD Access Method
* MODULE: Aligner.h
* DESCRIPTION: Aligner, OutAligner - templates to help
* with alignment on RISC machines.
* Should be used ONLY as temporary on-stack buffers!
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
*
* Software distributed under the License is distributed AS IS,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the License for the specific language governing rights
* and limitations under the License.
*
* The Original Code was created by Alexander Peshkoff
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2007 Alexander Peshkoff <peshkoff@mail.ru>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/

#ifndef CLASSES_ALIGN_H
#define CLASSES_ALIGN_H

#include "../common/classes/array.h"

namespace Firebird {

// Aligns output parameter (i.e. transfers data in destructor).
template <typename C>
class OutAligner {
private:
UCHAR* userBuffer;
#ifdef RISC_ALIGNMENT
Firebird::HalfStaticArray<C, BUFFER_SMALL> localBuffer;
ULONG bSize;
C* bPointer;
#endif

public:
OutAligner(UCHAR* buf, ULONG len) : userBuffer(buf)
#ifdef RISC_ALIGNMENT
, bSize(len), bPointer(0)
#endif
{
fb_assert(len % sizeof(C) == 0);
#ifdef RISC_ALIGNMENT
if ((IPTR) userBuffer & (sizeof(C) - 1))
{
bPointer = localBuffer.getBuffer(len / sizeof(C) + (bSize % sizeof(C) ? 1 : 0));
}
#endif
}

operator C*()
{
#ifdef RISC_ALIGNMENT
return bPointer ? bPointer : reinterpret_cast<C*>(userBuffer);
#else
return reinterpret_cast<C*>(userBuffer);
#endif
}

~OutAligner()
{
#ifdef RISC_ALIGNMENT
if (bPointer)
{
memcpy(userBuffer, bPointer, bSize);
}
#endif
}
};

// Aligns input parameter.
template <typename C>
class Aligner {
private:
#ifdef RISC_ALIGNMENT
Firebird::HalfStaticArray<C, BUFFER_SMALL> localBuffer;
#endif
const C* bPointer;

public:
Aligner(const UCHAR* buf, ULONG len)
{
fb_assert(len % sizeof(C) == 0);
#ifdef RISC_ALIGNMENT
if ((IPTR) buf & (sizeof(C) - 1))
{
C* tempPointer = localBuffer.getBuffer(len / sizeof(C) + (len % sizeof(C) ? 1 : 0));
memcpy(tempPointer, buf, len);
bPointer = tempPointer;
}
else
#endif
bPointer = reinterpret_cast<const C*>(buf);
}

operator const C*()
{
return bPointer;
}
};

} // namespace Firebird

#endif // CLASSES_ALIGN_H
4 changes: 2 additions & 2 deletions src/intl/cs_big5.cpp
Expand Up @@ -41,11 +41,11 @@ CHARSET_ENTRY(CS_big_5)
csptr->charset_fn_well_formed = CVBIG5_check_big5;

CV_convert_init(&csptr->charset_to_unicode,
reinterpret_cast<pfn_INTL_convert>(CVBIG5_big5_to_unicode),
CVBIG5_big5_to_unicode,
to_unicode_mapping_array,
to_unicode_map);
CV_convert_init(&csptr->charset_from_unicode,
reinterpret_cast<pfn_INTL_convert>(CVBIG5_unicode_to_big5),
CVBIG5_unicode_to_big5,
from_unicode_mapping_array,
from_unicode_map);

Expand Down
4 changes: 2 additions & 2 deletions src/intl/cs_gb2312.cpp
Expand Up @@ -41,11 +41,11 @@ CHARSET_ENTRY(CS_gb_2312)
csptr->charset_fn_well_formed = CVGB_check_gb2312;

CV_convert_init(&csptr->charset_to_unicode,
reinterpret_cast<pfn_INTL_convert>(CVGB_gb2312_to_unicode),
CVGB_gb2312_to_unicode,
to_unicode_mapping_array,
to_unicode_map);
CV_convert_init(&csptr->charset_from_unicode,
reinterpret_cast<pfn_INTL_convert>(CVGB_unicode_to_gb2312),
CVGB_unicode_to_gb2312,
from_unicode_mapping_array,
from_unicode_map);

Expand Down
16 changes: 6 additions & 10 deletions src/intl/cs_jis.cpp
Expand Up @@ -42,10 +42,10 @@ CHARSET_ENTRY(CS_jis_0208_1990)
csptr->charset_fn_well_formed = NULL;

CV_convert_init(&csptr->charset_to_unicode,
reinterpret_cast<pfn_INTL_convert>(CV_wc_to_wc),
CV_wc_to_wc,
to_unicode_mapping_array, to_unicode_map);
CV_convert_init(&csptr->charset_from_unicode,
reinterpret_cast<pfn_INTL_convert>(CV_wc_to_wc),
CV_wc_to_wc,
from_unicode_mapping_array,
from_unicode_map);
CHARSET_RETURN;
Expand All @@ -60,10 +60,8 @@ CHARSET_ENTRY(CS_sjis)
csptr->charset_min_bytes_per_char = 1;
csptr->charset_space_length = 1;
csptr->charset_space_character = (const BYTE*) " "; /* 0x20 */
csptr->charset_to_unicode.csconvert_fn_convert =
reinterpret_cast<pfn_INTL_convert>(CVJIS_sjis_to_unicode);
csptr->charset_from_unicode.csconvert_fn_convert =
reinterpret_cast<pfn_INTL_convert>(CVJIS_unicode_to_sjis);
csptr->charset_to_unicode.csconvert_fn_convert = CVJIS_sjis_to_unicode;
csptr->charset_from_unicode.csconvert_fn_convert = CVJIS_unicode_to_sjis;
CHARSET_RETURN;
}

Expand All @@ -76,9 +74,7 @@ CHARSET_ENTRY(CS_euc_j)
csptr->charset_min_bytes_per_char = 1;
csptr->charset_space_length = 1;
csptr->charset_space_character = (const BYTE*) " "; /* 0x20 */
csptr->charset_to_unicode.csconvert_fn_convert =
reinterpret_cast<pfn_INTL_convert>(CVJIS_eucj_to_unicode);
csptr->charset_from_unicode.csconvert_fn_convert =
reinterpret_cast<pfn_INTL_convert>(CVJIS_unicode_to_eucj);
csptr->charset_to_unicode.csconvert_fn_convert = CVJIS_eucj_to_unicode;
csptr->charset_from_unicode.csconvert_fn_convert = CVJIS_unicode_to_eucj;
CHARSET_RETURN;
}
4 changes: 2 additions & 2 deletions src/intl/cs_ksc.cpp
Expand Up @@ -42,11 +42,11 @@ CHARSET_ENTRY(CS_ksc_5601)
csptr->charset_fn_well_formed = CVKSC_check_ksc;

CV_convert_init(&csptr->charset_to_unicode,
reinterpret_cast<pfn_INTL_convert>(CVKSC_ksc_to_unicode),
CVKSC_ksc_to_unicode,
to_unicode_mapping_array,
to_unicode_map);
CV_convert_init(&csptr->charset_from_unicode,
reinterpret_cast<pfn_INTL_convert>(CVKSC_unicode_to_ksc),
CVKSC_unicode_to_ksc,
from_unicode_mapping_array,
from_unicode_map);

Expand Down
4 changes: 2 additions & 2 deletions src/intl/cs_narrow.cpp
Expand Up @@ -40,10 +40,10 @@ static void common_8bit_init(charset* csptr,
csptr->charset_space_character = (const BYTE*) " ";
csptr->charset_fn_well_formed = NULL;
CV_convert_init(&csptr->charset_to_unicode,
reinterpret_cast<pfn_INTL_convert>(CV_nc_to_unicode),
CV_nc_to_unicode,
to_unicode_tbl, NULL);
CV_convert_init(&csptr->charset_from_unicode,
reinterpret_cast<pfn_INTL_convert>(CV_unicode_to_nc),
CV_unicode_to_nc,
from_unicode_tbl1, from_unicode_tbl2);
}

Expand Down
4 changes: 2 additions & 2 deletions src/intl/cs_unicode_fss.cpp
Expand Up @@ -39,10 +39,10 @@ CHARSET_ENTRY(CS_unicode_fss)
csptr->charset_space_character = (const BYTE*) " "; /* 0x20 */
csptr->charset_fn_well_formed = NULL;
CV_convert_init(&csptr->charset_to_unicode,
reinterpret_cast<pfn_INTL_convert>(CS_UTFFSS_fss_to_unicode_cc),
CS_UTFFSS_fss_to_unicode_cc,
NULL, NULL);
CV_convert_init(&csptr->charset_from_unicode,
reinterpret_cast<pfn_INTL_convert>(CS_UTFFSS_unicode_to_fss),
CS_UTFFSS_unicode_to_fss,
NULL, NULL);
CHARSET_RETURN;
}
4 changes: 2 additions & 2 deletions src/intl/cs_unicode_ucs2.cpp
Expand Up @@ -38,10 +38,10 @@ CHARSET_ENTRY(CS_unicode_ucs2)
csptr->charset_space_character = (const BYTE*) & space; /* 0x0020 */
csptr->charset_fn_well_formed = NULL;
CV_convert_init(&csptr->charset_to_unicode,
reinterpret_cast<pfn_INTL_convert>(CV_wc_copy),
CV_wc_copy,
NULL, NULL);
CV_convert_init(&csptr->charset_from_unicode,
reinterpret_cast<pfn_INTL_convert>(CV_wc_copy),
CV_wc_copy,
NULL, NULL);
CHARSET_RETURN;
}
30 changes: 18 additions & 12 deletions src/intl/cv_big5.cpp
Expand Up @@ -31,25 +31,28 @@ ULONG CVBIG5_big5_to_unicode(csconvert* obj,
ULONG src_len,
const UCHAR* src_ptr,
ULONG dest_len,
USHORT *dest_ptr,
USHORT *err_code,
ULONG *err_position)
UCHAR* p_dest_ptr,
USHORT* err_code,
ULONG* err_position)
{
fb_assert(src_ptr != NULL || dest_ptr == NULL);
fb_assert(src_ptr != NULL || p_dest_ptr == NULL);
fb_assert(err_code != NULL);
fb_assert(err_position != NULL);
fb_assert(obj != NULL);
fb_assert(obj->csconvert_fn_convert == reinterpret_cast<pfn_INTL_convert>(CVBIG5_big5_to_unicode));
fb_assert(obj->csconvert_fn_convert == CVBIG5_big5_to_unicode);
fb_assert(obj->csconvert_impl->csconvert_datatable != NULL);
fb_assert(obj->csconvert_impl->csconvert_misc != NULL);

const ULONG src_start = src_len;
*err_code = 0;

/* See if we're only after a length estimate */
if (dest_ptr == NULL)
if (p_dest_ptr == NULL)
return (src_len * sizeof(USHORT));

Firebird::OutAligner<USHORT> d(p_dest_ptr, dest_len);
USHORT* dest_ptr = d;

USHORT wide;
USHORT this_len;
const USHORT* const start = dest_ptr;
Expand Down Expand Up @@ -104,17 +107,17 @@ ULONG CVBIG5_big5_to_unicode(csconvert* obj,

ULONG CVBIG5_unicode_to_big5(csconvert* obj,
ULONG unicode_len,
const USHORT* unicode_str,
const UCHAR* p_unicode_str,
ULONG big5_len,
UCHAR *big5_str,
USHORT *err_code,
ULONG *err_position)
UCHAR* big5_str,
USHORT* err_code,
ULONG* err_position)
{
fb_assert(unicode_str != NULL || big5_str == NULL);
fb_assert(p_unicode_str != NULL || big5_str == NULL);
fb_assert(err_code != NULL);
fb_assert(err_position != NULL);
fb_assert(obj != NULL);
fb_assert(obj->csconvert_fn_convert == reinterpret_cast<pfn_INTL_convert>(CVBIG5_unicode_to_big5));
fb_assert(obj->csconvert_fn_convert == CVBIG5_unicode_to_big5);
fb_assert(obj->csconvert_impl->csconvert_datatable != NULL);
fb_assert(obj->csconvert_impl->csconvert_misc != NULL);

Expand All @@ -125,6 +128,9 @@ ULONG CVBIG5_unicode_to_big5(csconvert* obj,
if (big5_str == NULL)
return (unicode_len); /* worst case - all han character input */

Firebird::Aligner<USHORT> s(p_unicode_str, unicode_len);
const USHORT* unicode_str = s;

const UCHAR* const start = big5_str;
while ((big5_len) && (unicode_len > 1)) {
/* Convert from UNICODE to BIG5 code */
Expand Down
4 changes: 2 additions & 2 deletions src/intl/cv_big5.h
Expand Up @@ -30,9 +30,9 @@
(UCHAR)((uc)&0xff)<=0xfe) /* BIG-5 2nd-byte */

ULONG CVBIG5_big5_to_unicode(csconvert* obj, ULONG src_len, const UCHAR* src_ptr,
ULONG dest_len, USHORT *dest_ptr,
ULONG dest_len, UCHAR *dest_ptr,
USHORT *err_code, ULONG *err_position);
ULONG CVBIG5_unicode_to_big5(csconvert* obj, ULONG unicode_len, const USHORT* unicode_str,
ULONG CVBIG5_unicode_to_big5(csconvert* obj, ULONG unicode_len, const UCHAR* unicode_str,
ULONG big5_len, UCHAR *big5_str,
USHORT *err_code, ULONG *err_position);
USHORT CVBIG5_check_big5(charset* cs, ULONG big5_len, const UCHAR* big5_str, ULONG* offending_position);
30 changes: 18 additions & 12 deletions src/intl/cv_gb2312.cpp
Expand Up @@ -31,25 +31,28 @@ ULONG CVGB_gb2312_to_unicode(csconvert* obj,
ULONG src_len,
const UCHAR* src_ptr,
ULONG dest_len,
USHORT *dest_ptr,
USHORT *err_code,
ULONG *err_position)
UCHAR* p_dest_ptr,
USHORT* err_code,
ULONG* err_position)
{
fb_assert(src_ptr != NULL || dest_ptr == NULL);
fb_assert(src_ptr != NULL || p_dest_ptr == NULL);
fb_assert(err_code != NULL);
fb_assert(err_position != NULL);
fb_assert(obj != NULL);
fb_assert(obj->csconvert_fn_convert == reinterpret_cast<pfn_INTL_convert>(CVGB_gb2312_to_unicode));
fb_assert(obj->csconvert_fn_convert == CVGB_gb2312_to_unicode);
fb_assert(obj->csconvert_impl->csconvert_datatable != NULL);
fb_assert(obj->csconvert_impl->csconvert_misc != NULL);

const ULONG src_start = src_len;
*err_code = 0;

/* See if we're only after a length estimate */
if (dest_ptr == NULL)
if (p_dest_ptr == NULL)
return (src_len * sizeof(USHORT));

Firebird::OutAligner<USHORT> d(p_dest_ptr, dest_len);
USHORT* dest_ptr = d;

USHORT wide;
USHORT this_len;
const USHORT* const start = dest_ptr;
Expand Down Expand Up @@ -105,17 +108,17 @@ ULONG CVGB_gb2312_to_unicode(csconvert* obj,

ULONG CVGB_unicode_to_gb2312(csconvert* obj,
ULONG unicode_len,
const USHORT* unicode_str,
const UCHAR* p_unicode_str,
ULONG gb_len,
UCHAR *gb_str,
USHORT *err_code,
ULONG *err_position)
UCHAR* gb_str,
USHORT* err_code,
ULONG* err_position)
{
fb_assert(unicode_str != NULL || gb_str == NULL);
fb_assert(p_unicode_str != NULL || gb_str == NULL);
fb_assert(err_code != NULL);
fb_assert(err_position != NULL);
fb_assert(obj != NULL);
fb_assert(obj->csconvert_fn_convert == reinterpret_cast<pfn_INTL_convert>(CVGB_unicode_to_gb2312));
fb_assert(obj->csconvert_fn_convert == CVGB_unicode_to_gb2312);
fb_assert(obj->csconvert_impl->csconvert_datatable != NULL);
fb_assert(obj->csconvert_impl->csconvert_misc != NULL);

Expand All @@ -126,6 +129,9 @@ ULONG CVGB_unicode_to_gb2312(csconvert* obj,
if (gb_str == NULL)
return (unicode_len); /* worst case - all han character input */

Firebird::Aligner<USHORT> s(p_unicode_str, unicode_len);
const USHORT* unicode_str = s;

const UCHAR* const start = gb_str;
while ((gb_len) && (unicode_len > 1)) {
/* Convert from UNICODE to GB2312 code */
Expand Down
6 changes: 3 additions & 3 deletions src/intl/cv_gb2312.h
Expand Up @@ -28,11 +28,11 @@
(UCHAR)((uc)&0xff)<=0xfe) /* GB2312 2nd-byte */

ULONG CVGB_gb2312_to_unicode(csconvert* obj, ULONG src_len, const UCHAR* src_ptr,
ULONG dest_len, USHORT *dest_ptr,
ULONG dest_len, UCHAR *dest_ptr,
USHORT *err_code, ULONG *err_position);

ULONG CVGB_unicode_to_gb2312(csconvert* obj, ULONG unicode_len, const USHORT* unicode_str,
ULONG gb_len,UCHAR *gb_str,
ULONG CVGB_unicode_to_gb2312(csconvert* obj, ULONG unicode_len, const UCHAR* unicode_str,
ULONG gb_len, UCHAR *gb_str,
USHORT *err_code, ULONG *err_position);

INTL_BOOL CVGB_check_gb2312(charset* cs, ULONG gb_len, const UCHAR* gb_str, ULONG* offending_position);

0 comments on commit 39fd59d

Please sign in to comment.