Skip to content

Commit f1f2ce5

Browse files
committed
Use strlcpy() in xrdp_init_xkb_layout()
Replace uses of g_strncpy() in xrdp_init_xkb_layout() with the more correct strlcpy(). In addition, some values and pointers which do not need to be writeable have been made const.
1 parent d73ce46 commit f1f2ce5

File tree

1 file changed

+93
-70
lines changed

1 file changed

+93
-70
lines changed

xrdp/lang.c

Lines changed: 93 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -496,21 +496,49 @@ km_load_file(const char *filename, struct xrdp_keymap *keymap)
496496
return rv;
497497
}
498498

499+
/*****************************************************************************/
500+
/***
501+
* looks up a keylayout in a list of values
502+
*
503+
* @param keylayout (e.g. 000000409)
504+
* @param items List of items (one of which is returned)
505+
* @param values List of hexadecimal lookup values
506+
* @param rdp_layout Buffer for result
507+
* @param rdp_layout_len Size of rdp_layout
508+
* @return != 0 for a successful lookup
509+
*/
510+
static int
511+
lookup_keylayout(int keylayout,
512+
const struct list *items,
513+
const struct list *values,
514+
char rdp_layout[], unsigned int rdp_layout_len)
515+
{
516+
int index;
517+
for (index = 0; index < items->count; index++)
518+
{
519+
const char *item = (const char *)list_get_item(items, index);
520+
const char *value = (const char *)list_get_item(values, index);
521+
if (g_atoix(value) == keylayout)
522+
{
523+
strlcpy(rdp_layout, item, rdp_layout_len);
524+
return 1;
525+
}
526+
}
527+
return 0;
528+
}
499529
/*****************************************************************************/
500530
void
501531
xrdp_init_xkb_layout(struct xrdp_client_info *client_info)
502532
{
503533
int fd;
504534
int index = 0;
505-
int bytes;
506-
struct list *names = (struct list *)NULL;
507-
struct list *items = (struct list *)NULL;
508-
struct list *values = (struct list *)NULL;
509-
char *item = (char *)NULL;
510-
char *value = (char *)NULL;
511-
char *q = (char *)NULL;
512-
char keyboard_cfg_file[256] = { 0 };
513-
char rdp_layout[256] = { 0 };
535+
struct list *names = NULL;
536+
struct list *items = NULL;
537+
struct list *values = NULL;
538+
const char *item = NULL;
539+
const char *value = NULL;
540+
const char *q = NULL;
541+
const char *keyboard_cfg_file = XRDP_CFG_PATH "/xrdp_keyboard.ini";
514542

515543
const struct xrdp_keyboard_overrides *ko =
516544
&client_info->xrdp_keyboard_overrides;
@@ -542,31 +570,34 @@ xrdp_init_xkb_layout(struct xrdp_client_info *client_info)
542570
}
543571
/* infer model/variant */
544572
/* TODO specify different X11 keyboard models/variants */
545-
g_memset(client_info->model, 0, sizeof(client_info->model));
546-
g_memset(client_info->variant, 0, sizeof(client_info->variant));
547-
g_strncpy(client_info->layout, "us", sizeof(client_info->layout) - 1);
573+
client_info->model[0] = '\0';
574+
client_info->variant[0] = '\0';
575+
strlcpy(client_info->layout, "us", sizeof(client_info->layout));
548576
if (client_info->keyboard_subtype == 3)
549577
{
550578
/* macintosh keyboard */
551-
bytes = sizeof(client_info->variant);
552-
g_strncpy(client_info->variant, "mac", bytes - 1);
579+
strlcpy(client_info->variant, "mac", sizeof(client_info->variant));
553580
}
554581
else if (client_info->keyboard_subtype == 0)
555582
{
556583
/* default - standard subtype */
557584
client_info->keyboard_subtype = 1;
558585
}
559586

560-
g_snprintf(keyboard_cfg_file, 255, "%s/xrdp_keyboard.ini", XRDP_CFG_PATH);
561587
LOG(LOG_LEVEL_DEBUG, "keyboard_cfg_file %s", keyboard_cfg_file);
562588

563589
fd = g_file_open_ro(keyboard_cfg_file);
564590

565591
if (fd >= 0)
566592
{
567593
int section_found = -1;
568-
char section_rdp_layouts[256] = { 0 };
569-
char section_layouts_map[256] = { 0 };
594+
char section_rdp_layouts[256];
595+
char section_layouts_map[256];
596+
char rdp_layout[256];
597+
598+
section_rdp_layouts[0] = '\0';
599+
section_layouts_map[0] = '\0';
600+
rdp_layout[0] = '\0';
570601

571602
names = list_create();
572603
names->auto_free = 1;
@@ -578,17 +609,17 @@ xrdp_init_xkb_layout(struct xrdp_client_info *client_info)
578609
file_read_sections(fd, names);
579610
for (index = 0; index < names->count; index++)
580611
{
581-
q = (char *)list_get_item(names, index);
582-
if (g_strncasecmp("default", q, 8) != 0)
612+
q = (const char *)list_get_item(names, index);
613+
if (g_strcasecmp("default", q) != 0)
583614
{
584615
int i;
585616

586617
file_read_section(fd, q, items, values);
587618

588619
for (i = 0; i < items->count; i++)
589620
{
590-
item = (char *)list_get_item(items, i);
591-
value = (char *)list_get_item(values, i);
621+
item = (const char *)list_get_item(items, i);
622+
value = (const char *)list_get_item(values, i);
592623
LOG(LOG_LEVEL_DEBUG, "xrdp_init_xkb_layout: item %s value %s",
593624
item, value);
594625
if (g_strcasecmp(item, "keyboard_type") == 0)
@@ -613,41 +644,40 @@ xrdp_init_xkb_layout(struct xrdp_client_info *client_info)
613644
{
614645
if (section_found != -1 && section_found == index)
615646
{
616-
g_strncpy(section_rdp_layouts, value, 255);
647+
strlcpy(section_rdp_layouts, value,
648+
sizeof(section_rdp_layouts));
617649
}
618650
}
619651
else if (g_strcasecmp(item, "layouts_map") == 0)
620652
{
621653
if (section_found != -1 && section_found == index)
622654
{
623-
g_strncpy(section_layouts_map, value, 255);
655+
strlcpy(section_layouts_map, value,
656+
sizeof(section_layouts_map));
624657
}
625658
}
626659
else if (g_strcasecmp(item, "model") == 0)
627660
{
628661
if (section_found != -1 && section_found == index)
629662
{
630-
bytes = sizeof(client_info->model);
631-
g_memset(client_info->model, 0, bytes);
632-
g_strncpy(client_info->model, value, bytes - 1);
663+
strlcpy(client_info->model, value,
664+
sizeof(client_info->model));
633665
}
634666
}
635667
else if (g_strcasecmp(item, "variant") == 0)
636668
{
637669
if (section_found != -1 && section_found == index)
638670
{
639-
bytes = sizeof(client_info->variant);
640-
g_memset(client_info->variant, 0, bytes);
641-
g_strncpy(client_info->variant, value, bytes - 1);
671+
strlcpy(client_info->variant, value,
672+
sizeof(client_info->variant));
642673
}
643674
}
644675
else if (g_strcasecmp(item, "options") == 0)
645676
{
646677
if (section_found != -1 && section_found == index)
647678
{
648-
bytes = sizeof(client_info->options);
649-
g_memset(client_info->options, 0, bytes);
650-
g_strncpy(client_info->options, value, bytes - 1);
679+
strlcpy(client_info->options, value,
680+
sizeof(client_info->options));
651681
}
652682
}
653683
else
@@ -676,15 +706,17 @@ xrdp_init_xkb_layout(struct xrdp_client_info *client_info)
676706
file_read_section(fd, "default", items, values);
677707
for (index = 0; index < items->count; index++)
678708
{
679-
item = (char *)list_get_item(items, index);
680-
value = (char *)list_get_item(values, index);
709+
item = (const char *)list_get_item(items, index);
710+
value = (const char *)list_get_item(values, index);
681711
if (g_strcasecmp(item, "rdp_layouts") == 0)
682712
{
683-
g_strncpy(section_rdp_layouts, value, 255);
713+
strlcpy(section_rdp_layouts, value,
714+
sizeof(section_rdp_layouts));
684715
}
685716
else if (g_strcasecmp(item, "layouts_map") == 0)
686717
{
687-
g_strncpy(section_layouts_map, value, 255);
718+
strlcpy(section_layouts_map, value,
719+
sizeof(section_layouts_map));
688720
}
689721
}
690722
list_clear(items);
@@ -693,53 +725,44 @@ xrdp_init_xkb_layout(struct xrdp_client_info *client_info)
693725

694726
/* load the map */
695727
file_read_section(fd, section_rdp_layouts, items, values);
696-
for (index = 0; index < items->count; index++)
728+
if (!lookup_keylayout(client_info->keylayout, items, values,
729+
rdp_layout, sizeof(rdp_layout)))
697730
{
698-
int rdp_layout_id;
699-
item = (char *)list_get_item(items, index);
700-
value = (char *)list_get_item(values, index);
701-
rdp_layout_id = g_atoix(value);
702-
if (rdp_layout_id == client_info->keylayout)
731+
if ((client_info->keylayout & ~0xffff) != 0)
703732
{
704-
g_strncpy(rdp_layout, item, 255);
705-
break;
706-
}
707-
}
708-
if (rdp_layout[0] == '\0' && (client_info->keylayout & ~0xffff) != 0)
709-
{
710-
// We failed to match the layout, but we may be able
711-
// to match on the lower 16-bits
712-
int alt_layout = client_info->keylayout & 0xffff;
713-
for (index = 0; index < items->count; index++)
714-
{
715-
item = (char *)list_get_item(items, index);
716-
value = (char *)list_get_item(values, index);
717-
int rdp_layout_id = g_atoix(value);
718-
if (rdp_layout_id == alt_layout)
733+
// We failed to match the layout, but we may be able
734+
// to match on the lower 16-bits
735+
int alt_layout = client_info->keylayout & 0xffff;
736+
if (lookup_keylayout(alt_layout, items, values,
737+
rdp_layout, sizeof(rdp_layout)))
719738
{
720-
g_strncpy(rdp_layout, item, 255);
721739
LOG(LOG_LEVEL_INFO,
722740
"Failed to match layout 0x%08X, but matched 0x%04X to %s",
723741
client_info->keylayout, alt_layout, rdp_layout);
724-
break;
725742
}
726743
}
727744
}
728745
list_clear(items);
729746
list_clear(values);
730-
file_read_section(fd, section_layouts_map, items, values);
731-
for (index = 0; index < items->count; index++)
747+
748+
// If we found a layout in the rdp layouts section, copy the
749+
// corresponding X11 layout name to the client layout, e.g. if we
750+
// matched 0xe0200411 to 'rdp_layout_jp, copy 'jp' for the client.
751+
if (rdp_layout[0] != '\0')
732752
{
733-
item = (char *)list_get_item(items, index);
734-
value = (char *)list_get_item(values, index);
735-
if (g_strcasecmp(item, rdp_layout) == 0)
753+
file_read_section(fd, section_layouts_map, items, values);
754+
for (index = 0; index < items->count; index++)
736755
{
737-
bytes = sizeof(client_info->layout);
738-
g_strncpy(client_info->layout, value, bytes - 1);
739-
break;
756+
item = (const char *)list_get_item(items, index);
757+
value = (const char *)list_get_item(values, index);
758+
if (g_strcasecmp(item, rdp_layout) == 0)
759+
{
760+
strlcpy(client_info->layout, value,
761+
sizeof(client_info->layout));
762+
break;
763+
}
740764
}
741765
}
742-
743766
list_delete(names);
744767
list_delete(items);
745768
list_delete(values);
@@ -756,8 +779,8 @@ xrdp_init_xkb_layout(struct xrdp_client_info *client_info)
756779
}
757780

758781
// Initialise the rules and a few keycodes for xorgxrdp
759-
snprintf(client_info->xkb_rules, sizeof(client_info->xkb_rules),
760-
"%s", scancode_get_xkb_rules());
782+
strlcpy(client_info->xkb_rules, scancode_get_xkb_rules(),
783+
sizeof(client_info->xkb_rules));
761784
if (keylayout_supports_caps_lock(client_info->keylayout))
762785
{
763786
client_info->x11_keycode_caps_lock =

0 commit comments

Comments
 (0)